On Fri, 2022-10-14 at 07:35 +1100, Richard Henderson wrote: > On 10/12/22 22:18, Ilya Leoshkevich wrote: > > Add ability to dump /tmp/perf-<pid>.map and jit-<pid>.dump. > > The first one allows the perf tool to map samples to each > > individual > > translation block. The second one adds the ability to resolve > > symbol > > names, line numbers and inspect JITed code. > > > > Example of use: > > > > perf record qemu-x86_64 -perfmap ./a.out > > perf report > > > > or > > > > perf record -k 1 qemu-x86_64 -jitdump ./a.out > > perf inject -j -i perf.data -o perf.data.jitted > > perf report -i perf.data.jitted > > > > Co-developed-by: Vanderson M. do Rosario <vanderson...@gmail.com> > > Co-developed-by: Alex Bennée <alex.ben...@linaro.org> > > Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com> > > I think I remember this, and the question that was never answered > was: > > > @@ -1492,6 +1493,8 @@ TranslationBlock *tb_gen_code(CPUState *cpu, > > } > > tb->tc.size = gen_code_size; > > > > + perf_report_code(gen_code_buf, gen_code_size, tb->icount, tb- > > >pc); > > When do_tb_flush is called, everything that is recorded in perfmap is > invalidated. > How do you tell perf about that? > > > r~ >
I don't think we should handle this altogether. Perf already knows how to handle overlapping addresses: $ cat main.c #include <dlfcn.h> #include <stdio.h> int main() { void *d = dlopen("./lib1.so", RTLD_NOW); void (*f)(void) = dlsym(d, "f"); printf("%p\n", f); f(); dlclose(d); d = dlopen("./lib2.so", RTLD_NOW); f = dlsym(d, "f"); printf("%p\n", f); f(); dlclose(d); } $ cat 1.c static volatile int i = 0; void f(void) { while (i < 1000000000) { i++; } } $ gcc -o main -O3 -g main.c -ldl $ gcc -o lib1.so -shared -fPIC -O3 -g 1.c $ cp 1.c 2.c $ gcc -o lib2.so -shared -fPIC -O3 -g 2.c $ perf record ./main 0x7f47925eb100 0x7f47925eb100 $ perf report 49.96% main lib1.so [.] f 49.92% main lib2.so [.] f Note that there is "load" event - PERF_RECORD_MMAP2, but no "unload" event. The old mappings are simply discarded by maps__fixup_overlappings() when something new is mapped. In our case this means that as soon as we JIT new code, perf will see that it replaced the one that was flushed. Until then it will live with stale mappings, but there is no harm in that, since they are not executed.