1

我尝试evince-3.28.4使用GDB. callq中的某个点有一条指令libdl,如下所示(即,在 处_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                              │

当执行到这里,回溯如下:

#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

但是当我输入ni(跳转到下一条汇编指令)时,它变成了这样:

#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

可以看出,经过简单的调用和返回,4 个元素被弹出栈。_dl_signal_cexception()< , __GI__dl_catch_exception()> 对可能有一些特别之处。call堆栈通过或以外的其他方式更改return。似乎_dl_signal_cexception()最终导致了一个修改回溯的__longjmp()函数。../sysdeps/x86_64/__longjmp.S有人可以描述这个过程吗?

4

1 回答 1

1

可以看出,经过简单的调用和返回,4 个元素被弹出栈。也许这对搭档有什么特别之处_dl_signal_cexception() __GI__dl_catch_exception()。堆栈通过调用或返回以外的其他方式更改。

正确:_dl_signal_exceptionreturn,它用于longjmp将控制权转移给它的调用者,而不是它的调用者 callers ... caller.

似乎_dl_signal_cexception()最终导致了一个__longjmp()

正确的。

有人可以描述这个过程吗?

你似乎不明白做什么longjmp。阅读它的手册页和/或这个例子应该会有所帮助。

更新:

即使与简单的 goto 相比,这种控制流转换的方法在某种程度上也是疯狂的……我应该考虑其他任何情况吗?

其他“有趣”的控制转移是 via和函数族makecontext,and (在 C++ 中)并且几乎等同于and 。setcontextswapcontextthrowcatchsetjmplongjmp

于 2020-02-23T15:33:29.263 回答