gdb 调试动态链接库

gdb) file <你的exe>
(gdb) load <你的so> #这条应该是可选的



(gdb) dir <so’dir>
(gdb) sharedlibrary <你的so>
(gdb) breakpoint <你的so中somewhere>
(gdb) run
load 是将动态库加载入内存。
sharedlibrary是将动态库的符号读入gdb,为了你能找到变量和函数名。
它们本身是没有明显的动作,但后面当你直接设置断点到动态库的函数(或行号)时,你就可以成功了。在此之前要记得用dir将动态库的源码也加入搜索路径

https://blog.csdn.net/weixin_30307267/article/details/98746387



(gdb) b zend_execute_ex
Function “zend_execute_ex” not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 3 (zend_execute_ex) pending.



(gdb) b execute_ex
Breakpoint 4 at 0x10055190c: file Zend/zend_vm_execute.h, line 417.



(gdb) run -f spl.php



(gdb) n



Breakpoint 6, execute_ex (ex=0x101a17030) at Zend/zend_vm_execute.h:432
432 if (UNEXPECTED((ret = ((opcode_handler_t)OPLINE->handler)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) != 0)) {
(gdb) n



xzm 6



xzm 2 spl_autoload



Program received signal SIGSEGV, Segmentation fault.
0x00007fff9a84fd32 in strlen () from /usr/lib/system/libsystem_c.dylib
(gdb) bt
#0 0x00007fff9a84fd32 in strlen () from /usr/lib/system/libsystem_c.dylib
#1 0x0000000101eb4257 in my_get_file_class_function_info ()
from /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
#2 0x0000000101eb41b3 in my_get_file_class_function_info ()
from /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
#3 0x0000000101eb3922 in my_execute_ex () from /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
#4 0x0000000100551b6a in zend_execute (op_array=0x101a72500, return_value=0x7fff5fbfdc90)
at Zend/zend_vm_execute.h:474
#5 0x0000000100320a07 in spl_autoload (class_name=0x101a03a40, lc_name=0x101a03ac0, ext=0x101a03a18 “.php”,
ext_len=4) at ext/spl/php_spl.c:289
#6 0x00000001003206d0 in zif_spl_autoload (execute_data=0x101a170c0, return_value=0x7fff5fbfe058)
at ext/spl/php_spl.c:334
#7 0x00000001004ce8b2 in zend_call_function (fci=0x7fff5fbfe018, fci_cache=0x7fff5fbfdff0)
at Zend/zend_execute_API.c:850
#8 0x00000001004cf27e in zend_lookup_class_ex (name=0x101a03a40, key=0x101a71140, use_autoload=1)
at Zend/zend_execute_API.c:1009
#9 0x00000001004d039f in zend_fetch_class_by_name (class_name=0x101a03a40, key=0x101a71140, fetch_type=512)
at Zend/zend_execute_API.c:1442
#10 0x000000010057db2e in ZEND_NEW_SPEC_CONST_HANDLER (execute_data=0x101a17030) at Zend/zend_vm_execute.h:3156
#11 0x0000000100551964 in execute_ex (ex=0x101a17030) at Zend/zend_vm_execute.h:432
#12 0x0000000101eb395f in my_execute_ex () from /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
#13 0x0000000100551b6a in zend_execute (op_array=0x101a72300, return_value=0x0) at Zend/zend_vm_execute.h:474
#14 0x00000001004eaf12 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at Zend/zend.c:1447
#15 0x0000000100440721 in php_execute_script (primary_file=0x7fff5fbff0b8) at main/main.c:2533
#16 0x00000001006062b5 in do_cli (argc=3, argv=0x100f00620) at sapi/cli/php_cli.c:990
#17 0x000000010060515a in main (argc=3, argv=0x100f00620) at sapi/cli/php_cli.c:1378



(gdb) load /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
You can’t do that when your target is `native’



gdb在eclipse远程调试时,自己写.gdbinit完后,执行load命令,出现you can’t do that when your target is exec’。有木有大神遇到过啊



https://stackoverflow.com/questions/3691394/gdb-meaning-of-tstart-error-you-cant-do-that-when-your-target-is-exec



调试失败的原因是因为gdb不能找到libggg.so,可以通过下面的方法解决:



1) 将库路径加到LD_LIBRARY_PATH里
2) 执行:ldconfig YOUR_LIB_PATH
3) 在/etc/ld.so.conf里加入库所在路径。然后执行:ldconfig



上面3个方法任意一个都可以,然后再去用gdb调试就没有问题了。
另:



1、假设我的可执行程序是ServerName,共享库为worker.so
2、我用gdb调试ServerName,想在B的某个源文件(比如worker.cpp,worker.cpp与ServerName不在同一个目录下)中设置断点,使用下面的命令行break worker.cpp:123



若找不到源文件可使用如下命令设定源文件目录:



设定gdb环境变量 LD_PRELOAD,在执行程序前先把共享库代码load进来
指定你的链接库的位置,可以通过设定环境变量LD_LIBRARY_PATH来实现



拷贝到标准的lib搜寻目录下,例如/usr/lib等



b main, r,然后再设置断点就可以了,共享库只有当程序运行才开始加载的



https://www.cnblogs.com/ybgame/archive/2012/03/23/2414078.html



如果我们没有把动态链接库放到指定目录,比如/lib里面,调试就会失败



http://grepkey.blog.chinaunix.net/uid-391024-id-2410433.html



(gdb) dir /usr/local/lib/php/extensions/debug-non-zts-20160303/
Source directories searched: /usr/local/lib/php/extensions/debug-non-zts-20160303:$cdir:$cwd



(gdb) sharedlibrary myFile.so
Symbols already loaded for /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so



(gdb) b my_get_file_class_function_info
Cannot access memory at address 0x1d90



(gdb) file <你的exe>
(gdb) load <你的so> #这条应该是可选的



(gdb) dir <so’dir>
(gdb) sharedlibrary <你的so>
(gdb) breakpoint <你的so中somewhere>
(gdb) run
load 是将动态库加载入内存。
sharedlibrary是将动态库的符号读入gdb,为了你能找到变量和函数名。
它们本身是没有明显的动作,但后面当你直接设置断点到动态库的函数(或行号)时,你就可以成功了。在此之前要记得用dir将动态库的源码也加入搜索路径。



https://cloud.tencent.com/developer/article/1392837





  1. 通过阅读 print_cvs 命令的实现,可以知道可以通过prev_execute_data来打印上一执行空间的PHP变量,如:
    (gdb) printzv *executor_globals.current_execute_data->prev_execute_data->CVs[1]

    [0x9543408] (refcount=1) string(3): “AAA”
    (gdb) printzv *executor_globals.current_execute_data->prev_execute_data->CVs[2]

    [0x95433ec] (refcount=1) string(3): “BBB”
    (gdb)




  2. 通过 op_array->vars 来找到对应的变量的名字
    (gdb) printf “%s\n” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[1].name

    a
    (gdb) printf “%s\n” ,executor_globals.current_execute_data->prev_execute_data->op_array->vars[2].name

    b




  3. 修改了一下 print_cvs 命令,通过参数来获取每个执行空间的PHP的已编译变量
    define print_cvs
    ____executor_globals
    set $f = $eg.current_execute_data
    if $argc == 1
    set $j = 1
    while $j < $arg0 && $f.prev_execute_data != 0
    set $f = $f.prev_execute_data
    set $j = $j + 1
    end
    end
    set $p = $f.CVs
    set $c = $f.op_array.last_var
    set $v = $f.op_array.vars
    set $i = 0
    printf “Compiled variables count: %d\n”, $c
    while $i < $c
    printf “%d = %s\n”, $i, $v[$i].name
    if $p[$i] != 0
    printzv $p[$i]
    else
    printf “
    uninitialized*\n”
    end
    set $i = $i + 1
    end
    end





使用方法:
———————
(gdb) zbacktrace #查看PHP的调用栈
[0x8ce2078] sleep(1) /usr/home/junjie2/a.php:9
[0x8ce1fe0] test(“phpor”) /usr/home/junjie2/a.php:5
(gdb) print_cvs #查看当前执行空间中的PHP变量
Compiled variables count: 3
0 = name
[0x8cae3d0] (refcount=2) string(5): “phpor”
1 = m
[0x8cae93c] (refcount=1) string(3): “MMM”
2 = n
[0x8cae958] (refcount=1) string(3): “NNN”
(gdb) print_cvs 2 # 查看指定执行空间中的PHP变量, 这个参数给大了也没关系,最多打印最外层的PHP变量
Compiled variables count: 2
0 = a
[0x8cae408] (refcount=1) string(3): “AAA”
1 = b
[0x8cae3ec] (refcount=1) string(3): “BBB”
(gdb)
———————





  1. 有时候需要借助环境变量,如:
    (gdb) print_ft (HashTable *)0xa5bd450
    A syntax error in expression, near `’.
    (gdb) set $phpor=(HashTable *)0xa5bd450
    (gdb) print_ft $phpor
    [0xa5bd450] {
    “zend_version\0″ => “zend_version”
    “func_num_args\0″ => “func_num_args”
    “func_get_arg\0″ => “func_get_arg”
    “func_get_args\0″ => “func_get_args”
    “strlen\0″ => “strlen”
    “strcmp\0″ => “strcmp”
    “strncmp\0″ => “strncmp”




  2. 打印指定的PHP变量





https://blog.csdn.net/xiaolei1982/article/details/20584291



https://www.zhihu.com/question/20348619?sort=created



初步怀疑没有调试信息,重新编译扩展
$./configure –enable-debug –enable-static=0
make & make install
$sudo gdb php
(gdb) source /Users/didi/PhpstormProjects/c/php-src/.gdbinit
(gdb) run -f spl.php



(gdb) dir /usr/local/lib/php/extensions/debug-non-zts-20160303/
Source directories searched: /usr/local/lib/php/extensions/debug-non-zts-20160303:$cdir:$cwd
(gdb) sharedlibrary myFile.so
Symbols already loaded for /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
(gdb) b my_get_file_class_function_info
Cannot access memory at address 0x1d90
(gdb) b
Breakpoint 1 at 0x7fff9a84fd32
(gdb) b zend_execute
Breakpoint 2 at 0x100551a97: file Zend/zend_vm_execute.h, line 461.



https://blog.csdn.net/u012684933/article/details/44060769



(gdb) dir /usr/local/lib/php/extensions/debug-non-zts-20160303/
Source directories searched: /usr/local/lib/php/extensions/debug-non-zts-20160303:$cdir:$cwd
(gdb) sharedlibrary myFile.so
No loaded shared libraries match the pattern myFile.so'.
(gdb) sharedlibrary /usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so
No loaded shared libraries match the pattern
/usr/local/lib/php/extensions/debug-non-zts-20160303/myFile.so’.



(gdb) load myFile.so
You can’t do that when your target is exec'
(gdb) sharedlibrary myFile.so
No loaded shared libraries match the pattern
myFile.so’.



(gdb) file php
Load new symbol table from “php”? (y or n) y
Reading symbols from php…done.



(gdb) dir /usr/local/lib/php/extensions/debug-non-zts-20160303/
Source directories searched: /usr/local/lib/php/extensions/debug-non-zts-20160303:$cdir:$cwd
(gdb) sharedlibrary myFile.so
No loaded shared libraries match the pattern myFile.so'.
(gdb) load myFile.so
You can't do that when your target is
exec’
https://stackoverflow.com/questions/37641967/how-to-debug-a-shared-library-using-gdb



This implies a bug in GDB. Unfortunately your version of GDB is too old for developers to care. Try reproducing this behavior with current GDB 7.11.1, and file a bug in GDB bugzilla if it does reproduce.



If you don’t want to use GDB 7.11.1, you can work around this bug by setting a breakpoint after the shared library has been loaded.



If the library is linked into the main executable directly, the following sequence should work:



(gdb) start


GDB stop on entry to main



(gdb) b FileOfSharedLib.c:NNN # should find the source now
If the library is dlopened, you’ll need to set a temporary breakpoint in the main exectable somewhere after that dlopen.



Another workaround: set stop-on-solib-events 1. This will make GDB stop after any new shared library is added (or removed).



(gdb) set stop-on-solib-events 1
(gdb)
(gdb) run -f spl.php
Starting program: /usr/local/bin/php -f spl.php
Stopped due to shared library event:
Inferior loaded /usr/lib/libresolv.9.dylib
/usr/lib/libiconv.2.dylib
/usr/lib/libSystem.B.dylib
/usr/lib/libxml2.2.dylib
/usr/lib/libz.1.dylib
(gdb) c
Continuing.
Stopped due to shared library event:
Inferior loaded /usr/local/lib/php/extensions/debug-non-zts-20160303/zlib.so
(gdb)



(gdb) b spl_autoload
Breakpoint 1 at 0x10032084b: file ext/spl/php_spl.c, line 257.



https://www.cnblogs.com/yjf512/archive/2016/12/01/6120856.html
https://blog.csdn.net/weixin_34405354/article/details/90652400
https://zhuanlan.zhihu.com/p/67916872



(gdb) p *(execute_data->func->op_array.filename)
$7 = {gc = {refcount = 3, u = {v = {type = 6 ‘\006’, flags = 0 ‘\000’, gc_info = 0}, type_info = 6}}, h = 17817666378049475646, len = 55,
val = “/”}
(gdb) s



xzm 6



xzm 2 spl_autoload



Program received signal SIGSEGV, Segmentation fault.
0x00007fff9a84fd32 in strlen () from /usr/lib/system/libsystem_c.dylib



https://blog.csdn.net/fff058/article/details/78692261
https://type.so/c/php-extension-in-action-get-arguments-after-zend-execute-ex.html



Category php