Reputation: 940
I tried to trace evince-3.28.4
execution using GDB
. There is a callq
instruction at some point in libdl
, which is shown below (i.e., at _dl_lookup_symbol_x+840
):
│0x7ffff7de03f5 <_dl_lookup_symbol_x+837> mov %rbx,%rsi │
>│0x7ffff7de03f8 <_dl_lookup_symbol_x+840> callq 0x7ffff7df0b00 <_dl_signal_cexception> │
│0x7ffff7de03fd <_dl_lookup_symbol_x+845> mov %rbx,%rdi │
When the execution reaches here, the backtrace is as follows:
#0 0x00007ffff7de03f8 in _dl_lookup_symbol_x (undef_name=0x7ffff744fa23 "gtk_progress_get_type", undef_map=0x7ffff7ffe170, ref=0x7fffffffd8d8, symbol_scope=0x7ffff7ffe4f8, version=0x0, type_class=0, flags=2, skip_map=<optimized out>) at dl-lookup.c:857
#1 0x00007ffff4bd6da6 in do_sym (flags=2, vers=0x0, who=0x7ffff486d48e <g_module_symbol+126>, name=0x7ffff744fa23 "gtk_progress_get_type", handle=0x7ffff7ffe170)
at dl-sym.c:151
#2 0x00007ffff4bd6da6 in _dl_sym (handle=0x7ffff7ffe170, name=0x7ffff744fa23 "gtk_progress_get_type", who=0x7ffff486d48e <g_module_symbol+126>) at dl-sym.c:254
#3 0x00007fffefcdf0e4 in dlsym_doit (a=a@entry=0x7fffffffdb20) at dlsym.c:50
#4 0x00007ffff4bd72df in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdab0, operate=0x7fffefcdf0d0 <dlsym_doit>, args=0x7fffffffdb20)
at dl-error-skeleton.c:196
#5 0x00007ffff4bd736f in __GI__dl_catch_error (objname=0x5555557d44a0, errstring=0x5555557d44a8, mallocedp=0x5555557d4498, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:215
#6 0x00007fffefcdf735 in _dlerror_run (operate=operate@entry=0x7fffefcdf0d0 <dlsym_doit>, args=args@entry=0x7fffffffdb20) at dlerror.c:162
#7 0x00007fffefcdf166 in __dlsym (handle=handle@entry=0x7ffff7ffe170, name=name@entry=0x7ffff744fa23 "gtk_progress_get_type") at dlsym.c:70
#8 0x00007ffff486d48e in _g_module_symbol (symbol_name=0x7ffff744fa23 "gtk_progress_get_type", handle=0x7ffff7ffe170) at ../../../../gmodule/gmodule-dl.c:163
#9 0x00007ffff486d48e in g_module_symbol (module=module@entry=0x5555557d44c0, symbol_name=symbol_name@entry=0x7ffff744fa23 "gtk_progress_get_type", symbol=symbol@entry=0x7fffffffdba0) at ../../../../gmodule/gmodule.c:800
#10 0x00007ffff728f55e in _gtk_module_has_mixed_deps (module_to_check=module_to_check@entry=0x0) at ../../../../gtk/gtkmodules.c:594
#11 0x00007ffff728f703 in find_module (name=0x5555557db040 "gail") at ../../../../gtk/gtkmodules.c:227
#12 0x00007ffff728f703 in load_module (name=0x5555557db040 "gail", module_list=0x0) at ../../../../gtk/gtkmodules.c:292
#13 0x00007ffff728f703 in load_modules (module_str=module_str@entry=0x5555557d44f0 "gail:atk-bridge") at ../../../../gtk/gtkmodules.c:423
#14 0x00007ffff728fb64 in _gtk_modules_init (argc=0x0, argv=<optimized out>, gtk_modules_args=0x5555557d44f0 "gail:atk-bridge") at ../../../../gtk/gtkmodules.c:544
#15 0x00007ffff726786b in do_post_parse_initialization (argc=0x0, argv=0x0) at ../../../../gtk/gtkmain.c:755
#16 0x00007ffff726786b in post_parse_hook (context=<optimized out>, group=<optimized out>, data=0x5555557d0cd0, error=0x7fffffffdd98) at ../../../../gtk/gtkmain.c:798
#17 0x00007ffff54768a8 in g_option_context_parse (context=<optimized out>, argc=<optimized out>, argv=<optimized out>, error=<optimized out>)
at ../../../../glib/goption.c:2165
#18 0x0000555555573386 in main (argc=<optimized out>, argv=<optimized out>) at main.c:275
But when I enter ni
(to jump to the next assembly instruction), it turns into this:
#0 0x00007ffff4bd72cd in __GI__dl_catch_exception (exception=exception@entry=0x7fffffffdab0, operate=0x7fffefcdf0d0 <dlsym_doit>, args=0x7fffffffdb20)
at dl-error-skeleton.c:194
#1 0x00007ffff4bd736f in __GI__dl_catch_error (objname=0x5555557d44a0, errstring=0x5555557d44a8, mallocedp=0x5555557d4498, operate=<optimized out>, args=<optimized out>) at dl-error-skeleton.c:215
#2 0x00007fffefcdf735 in _dlerror_run (operate=operate@entry=0x7fffefcdf0d0 <dlsym_doit>, args=args@entry=0x7fffffffdb20) at dlerror.c:162
#3 0x00007fffefcdf166 in __dlsym (handle=handle@entry=0x7ffff7ffe170, name=name@entry=0x7ffff744fa23 "gtk_progress_get_type") at dlsym.c:70
#4 0x00007ffff486d48e in _g_module_symbol (symbol_name=0x7ffff744fa23 "gtk_progress_get_type", handle=0x7ffff7ffe170) at ../../../../gmodule/gmodule-dl.c:163
#5 0x00007ffff486d48e in g_module_symbol (module=module@entry=0x5555557d44c0, symbol_name=symbol_name@entry=0x7ffff744fa23 "gtk_progress_get_type", symbol=symbol@entry=0x7fffffffdba0) at ../../../../gmodule/gmodule.c:800
#6 0x00007ffff728f55e in _gtk_module_has_mixed_deps (module_to_check=module_to_check@entry=0x0) at ../../../../gtk/gtkmodules.c:594
#7 0x00007ffff728f703 in find_module (name=0x5555557db040 "gail") at ../../../../gtk/gtkmodules.c:227
#8 0x00007ffff728f703 in load_module (name=0x5555557db040 "gail", module_list=0x0) at ../../../../gtk/gtkmodules.c:292
#9 0x00007ffff728f703 in load_modules (module_str=module_str@entry=0x5555557d44f0 "gail:atk-bridge") at ../../../../gtk/gtkmodules.c:423
#10 0x00007ffff728fb64 in _gtk_modules_init (argc=0x0, argv=<optimized out>, gtk_modules_args=0x5555557d44f0 "gail:atk-bridge") at ../../../../gtk/gtkmodules.c:544
#11 0x00007ffff726786b in do_post_parse_initialization (argc=0x0, argv=0x0) at ../../../../gtk/gtkmain.c:755
#12 0x00007ffff726786b in post_parse_hook (context=<optimized out>, group=<optimized out>, data=0x5555557d0cd0, error=0x7fffffffdd98) at ../../../../gtk/gtkmain.c:798
#13 0x00007ffff54768a8 in g_option_context_parse (context=<optimized out>, argc=<optimized out>, argv=<optimized out>, error=<optimized out>)
at ../../../../glib/goption.c:2165
#14 0x0000555555573386 in main (argc=<optimized out>, argv=<optimized out>) at main.c:275
As can be seen, after a simple call and return, 4 elements are popped off the stack. Perhaps there is something special about the <_dl_signal_cexception()
, __GI__dl_catch_exception()
> pair. The stack is changed by some means other than call
or return
. It seems that _dl_signal_cexception()
finally leads to a __longjmp()
function at ../sysdeps/x86_64/__longjmp.S
which modifies the backtrace. Can someone describe the process?
Upvotes: 1
Views: 162
Reputation: 213375
As can be seen, after a simple call and return, 4 elements are popped off the stack. Perhaps there is something special about the
_dl_signal_cexception()
__GI__dl_catch_exception()
pair. The stack is changed by some means other than call or return.
Correct: the _dl_signal_exception
doesn't return
, it uses longjmp
to transfer control not to its caller, but to its callers callers ... caller.
It seems that
_dl_signal_cexception()
finally leads to a__longjmp()
Correct.
Can someone describe the process?
You appear to not understand what longjmp
does. Reading its man page and/or this example should help.
Update:
this approach for transition in control flow is somehow insane even compared to simple gotos ... any other cases that I should consider?
Other "interesting" control transfers are via makecontext
, setcontext
and swapcontext
family of functions, and (in C++) throw
and catch
are pretty much equivalent to setjmp
and longjmp
.
Upvotes: 1