GDB and Frame-Filters: a bug and a quick fix
With frame filters and decorators, GDB lets you rewrite the output of the where command. That's quite convenient, except that it doesn't work well in one situation (that I could not clearly understand ...):
(gdb) where no-filters # <--- notice the option here #0 do_spin () at .../gcc-5.2.0/libgomp/config/linux/wait.h:55 #1 do_wait () at ...gcc-5.2.0//libgomp/config/linux/wait.h:64 #2 gomp_team_barrier_wait_end (...) at .../libgomp/config/linux/bar.c:112 #3 0x00007ffff7bd8966 in GOMP_barrier () at gomp_preload.c:49 #4 0x0000000000400a19 in main._omp_fn.0 () at parallel-demo.c:10 #5 0x00007ffff7bd89e4 in GOMP_parallel_trampoline (...) at gomp_preload.c:62 #6 0x00007ffff79c442e in gomp_thread_start () at .../libgomp/team.c:118 #7 0x00007ffff7bd8ce8 in pthread_create_trampoline () at pthread_preload.c:33 #8 0x00007ffff779f4a4 in start_thread () from /usr/lib/libpthread.so.0 #9 0x00007ffff74dd13d in clone () from /usr/lib/libc.so.6
becomes:
(gdb) where #0 gomp_team_barrier_wait_end () at .../libgomp/config/linux/wait.h:55 #1 gomp_team_barrier_wait_end () at .../libgomp/config/linux/wait.h:64 #2 #pragma omp barrier () at parallel-demo.c:10 #4 #parallel zone #1 of main () at parallel-demo.c:10
Many frames are gone, that's my cleanup, some function names have been changed, that's my OpenMP work ... but the function name of frame #0 and #1 are inconsistent. It should not read gomp_team_barrier_wait_end but rather do_spin and do_wait, respectively.
I don't know what's special about these functions, they're inlined, but that's not enough to explain and recreate the problem ...
Anyway, I found that the inconsistency boils down to two lines:
(gdb) frame 0 (gdb) pi print(gdb.selected_frame().function()) gomp_team_barrier_wait_end # wrong (gdb) pi print(gdb.selected_frame().name()) do_spin # right
So to solve my problem, I add a frame decorator that picks up the frame name instead of its function symbol:
class BugFixFrame(gdb.frames.FrameDecorator): def function(self): return self.inferior_frame().name() class BugFixFrameFilter: def __init__(self): self.enabled = True self.priority = 99999 def filter(self, frames): for frame in frames: yield BugFixFrame(frame) gdb.frame_filters["Bug fix frame filter"] = BugFixFrameFilter()
and I now have my clean and correct callstack:
(gdb) where #0 do_spin (val=0, addr=0x602104) at .../libgomp/config/linux/wait.h:55 #1 do_wait (val=0, addr=0x602104) at .../libgomp/config/linux/wait.h:64 #2 #pragma omp barrier () at parallel-demo.c:10 #4 #parallel zone #1 of main () at parallel-demo.c:10
I've submitted a bug report as PR/19225.