[原创]转载请注明来源于CSDN _xiao。
在Linux生成Coredump文件时程序并没有对动态链接库文件信息进行特殊处理,但GDB在载入Coredump文件时却能正确加载所有的动态链接库,包括程序运行中调用dlopen动态载入的so文件,其原理是什么呢?这里通过对GDB源码的略览来解开这个过程。
[关于如何设置库搜索路径以及路径搜索的优先级可参考"GDB动态库搜索路径"笔记]
GDB的大略架构:gdb.c中的main函数是程序的入口,它只是简单地调用gdb_main,后者再调用captured_main,captured_main是执行的主体函数。它先解析命令行参数选项,再初始化所有变量和所有文件,最后是一个while循环,这个循环里不断调用captured_command_loop来获取输入的命令并执行命令所指示的动作。其中初始化时gdb_init会调用initialize_all_files函数来初始化所有文件,这个函数在编译之前是看不到的,在编译时Makefile会扫描所有源文件,将所有类型为initialize_file_ftype的函数搜集起来,放在gdb目录下新生成的init.c文件中,并在此文件中创建initialize_all_files函数,此函数依次调用每一个_initialize_xxx函数。模块在自己的_initialize_xxx函数中除了初始化自身外,还会调用add_cmd或类似的函数来注册命令,之后用户输入所注册的命令时就会调用模块的处理函数了。例如corefile.c文件在_initialize_core函数中注册了"core-file”命令,命令的处理函数是core_file_command,这样当用户敲入"core Coredump”时就会调用core_file_command函数来处理了("core”是"core-file”命令的别名)。同样exec.c注册了"file”指令,其处理函数为file_command。通常,命令"xxx”的处理函数名为"xxx_command”,例如"info sharedLibrary”命令的处理函数为info_sharedlibrary_command,根据此规则,可以快速找到命令的处理函数。
载入一个Coredump文件时,由core_file_command来处理,首先通过find_core_target来查找有能力处理"CORE”文件的target,并调用target的open函数处理。corelow.c在初始化时注册了该类型的target,所以会进入corelow.c的core_open函数。core_open函数调用bfd_fopen函数打开该文件(bfd_fopen会识别格式并按ELF格式打开),然后调用build_section_table