Compare commits

...

5 commits

5 changed files with 191 additions and 8 deletions

108
.gitignore vendored
View file

@ -1,3 +1,111 @@
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# Normal rules (sorted alphabetically)
#
.*
*.a
*.asn1.[ch]
*.bin
*.bz2
*.c.[012]*.*
*.dtb
*.dtb.S
*.dwo
*.elf
*.gcno
*.gz
*.i
*.ko
*.lex.c
*.ll
*.lst
*.lz4
*.lzma
*.lzo
*.mod.c
*.o
*.o.*
*.order
*.patch
*.s
*.so
*.so.dbg
*.su
*.symtypes
*.tab.[ch]
*.tar
*.xz
Module.symvers
modules.builtin
#
# RPM spec file (make rpm-pkg)
#
/*.spec
#
# git files that we don't want to ignore even if they are dot-files
#
!.gitignore
!.mailmap
!.cocciconfig
!.clang-format
#
# Generated include files
#
include/config
include/generated
include/ksym
arch/*/include/generated
# stgit generated dirs
patches-*
# quilt's files
patches
series
# cscope files
cscope.*
ncscope.*
# gnu global files
GPATH
GRTAGS
GSYMS
GTAGS
# id-utils files
ID
*.orig
*~
\#*#
#
# Leavings from module signing
#
extra_certificates
signing_key.pem
signing_key.priv
signing_key.x509
x509.genkey
# Kconfig presets
all.config
# Kdevelop4
*.kdev4
# Perf specific
PERF-CFLAGS
PERF-GUI-VARS
PERF-VERSION-FILE

25
README.md Normal file
View file

@ -0,0 +1,25 @@
# Perf, `eh_elf` flavour
This repository contains a fork of perf, the profiler from the Linux kernel
repository, modified in a way to interface it with `eh_elfs` and (hopefully)
speeding it up on complicated DWARF frames
## Compiling
Clone the [Linux kernel
repository](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git)
or get a tarball of its source tree, then replace the `tools/perf` directory
with a clone of this repo. If you wish to clone the Linux source tree, and if
you're not going to work on it, you might consider passing `--depth=1` to `git
clone`, in order not to download the history, to keep the download light.
Then, `cd tools/perf` and `make`, without forgetting to give the compilation
tools the right version of `libunwind`, eg. by setting `LD_RUN_PATH` and
`LIBUNWIND_DIR`:
```sh
export LD_RUN_PATH=$HOME/local/libunwind/lib
export LIBUNWIND_DIR=$HOME/local/libunwind
make
```
This works at least with the linux repository at v4.17-rc5

View file

@ -54,6 +54,8 @@
#include <unistd.h>
#include <linux/mman.h>
#include <libunwind.h>
struct report {
struct perf_tool tool;
struct perf_session *session;
@ -1398,6 +1400,8 @@ repeat:
} else
ret = 0;
chrono_report_disp();
error:
zfree(&report.ptime_range);

43
make-target Executable file
View file

@ -0,0 +1,43 @@
#!/bin/bash
case "$1" in
'eh_elf')
TARGET='eh_elf'
LIBUNWIND='eh_elf'
branch='eh_elf'
;;
'vanilla')
TARGET='vanilla'
LIBUNWIND='vanilla'
branch='vanilla_timer'
;;
'vanilla-nocache')
TARGET='vanilla-nocache'
LIBUNWIND='vanilla'
branch='vanilla_timer_nocache'
;;
*)
>&2 echo "Usage: $0 [ eh_elf | vanilla | vanilla-nocache ]"
exit 1
esac
original_branch=$(git rev-parse --abbrev-ref HEAD)
if ! git checkout "$branch" ; then
>&2 echo "Failed to checkout $branch - maybe your git isn't clean?"
exit 2
fi
LIBUNWIND_PREFIX="$HOME/local/libunwind-$LIBUNWIND-dbg"
LIBUNWIND_LIB="$LIBUNWIND_PREFIX/lib"
PREFIX="$HOME/local/perf-$TARGET"
export CPATH=$LIBUNWIND_PREFIX/include
export LD_LIBRARY_PATH=$LIBUNWIND_LIB
export EXTRA_CFLAGS=-L$LIBUNWIND_LIB
make -j
mkdir -p $PREFIX/bin
cp "perf" "$PREFIX/bin/"
git checkout "$original_branch"

View file

@ -473,10 +473,11 @@ get_proc_name(unw_addr_space_t __maybe_unused as,
}
static void
get_mmap(unw_mmap_entry_t* entries, size_t* count, void* arg) {
get_mmap(unw_mmap_entry_t** entries, size_t* count, void* arg) {
struct unwind_info* unw_info = arg;
struct map_groups* mgroups = unw_info->thread->mg;
int id;
unw_mmap_entry_t* alloc_entries = NULL;
// == Count entries ==
*count = 0;
@ -488,8 +489,9 @@ get_mmap(unw_mmap_entry_t* entries, size_t* count, void* arg) {
}
// == Allocate ==
entries = (unw_mmap_entry_t*)
malloc(sizeof(unw_mmap_entry_t) * (*count)); // Will be free'd
alloc_entries = (unw_mmap_entry_t*)
malloc(sizeof(unw_mmap_entry_t) * (*count)); // Will be free'd by user
*entries = alloc_entries;
// == Fill entries ==
id = 0;
@ -497,11 +499,12 @@ get_mmap(unw_mmap_entry_t* entries, size_t* count, void* arg) {
map;
map = map_groups__next(map), ++id)
{
entries[id].beg_ip = map->start;
entries[id].end_ip = map->end;
entries[id].offset = map->start - map->map_ip(map, map->start);
entries[id].object_name = malloc(strlen(map->dso->long_name) + 1);
strcpy(entries[id].object_name, map->dso->long_name);
alloc_entries[id].beg_ip = map->start;
alloc_entries[id].end_ip = map->end;
alloc_entries[id].offset = map->start - map->map_ip(map, map->start);
alloc_entries[id].object_name =
malloc(strlen(map->dso->long_name) + 1);
strcpy(alloc_entries[id].object_name, map->dso->long_name);
}
}