----------------------------------------
warning: File "/home/hjj/work/customed_server/session_manager/.gdbinit"
auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
----------------------------------------
解决办法
gdb -iex "set auto-load safe-path /"
根本解决办法;
在家目录下编辑.gdbinit, 加上 set auto-load safe-path /
查验:
info auto-load
----------------------------------------
gdb 源码路径 ---- elf 文件的 .debug_str 节。
----------------------------------------
readelf -S /usr/local/sbin/nginx 可以看到 nginx 的很多节。
今天特别关注.debug_str 节
前面的几个是全局符号, 其中重要的有一个源代码绝对根路径
readelf -p .debug_str /usr/local/nginx/sbin/nginx |grep hjj
[ 1c1] /home/hjj/Downloads/nginx-1.7.6
后面是属于不同文件的符号表, 由相对文件名称来引领。
符号可以是变量名称,函数名称,类型名称等等..
方括号括住的是该符号相对于符号表的地址偏移
[/pts/1@hjj ~]$ readelf -p .debug_str /usr/local/nginx/sbin/nginx
[ 27e] src/core/nginx.c
[ 28f] ngx_prefix
[ 29a] valid_info
[ 2a5] ngx_uid_t
[ 2af] ngx_write_fd
[ 2bc] wdata
[ 2c2] long long unsigned int
...
[ cc4] src/core/ngx_log.c
...
[ f68] src/core/ngx_palloc.c
...
[ fff] src/core/ngx_array.c
...
有了debug_str 节,就可以找到bin文件对应的源文件,
注意: .debug_str 节只有.c,.cpp 源文件信息,.h 文件则不在此处包含
其实,当你废了很大劲时,才发现由更好的方法达到目的, 要查看绝对路径,在gdb中用下面命令:
(gdb) info source
Current source file is src/core/nginx.c
Compilation directory is /home/hjj/Downloads/nginx-1.7.6
Located in /home/hjj/Downloads/nginx-1.7.6/src/core/nginx.c
Contains 1363 lines.
Source language is c.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
(gdb) info sources
将更加详细的列出所有.c, .h 源文件
.....
------------------------------------------------------------
gdb 扩展: 打印qt的 QString 变量和QByteArray 变量
可以把它放大gdbinit 中, 用source gdbinit 来加载
------------------------------------------------------------
for QT4
define pqstring
set $i=0
while $i < $arg0.d->size
set $c=$arg0.d->data[$i++]
if $c < 32 || $c > 127
printf "0x%04x", $c
else
printf "%c", (char)$c
end
end
printf "\n"
end
For QT5 define pqs printf "(QString)0x%x (length=%i, offset=%i, ref=%x): \"",&$arg0,$arg0.d->size,$arg0.d->offset,&$arg0.d->ref set $i=0 set $off=$arg0.d->offset set $base=(void*)(&$arg0.d->ref) + $off while $i < $arg0.d->size set $c=((short*)$base)[$i++] if $c < 32 || $c > 127 printf "\\u0x%04x", $c else printf "%c", (char)$c end end printf "\"\n" end
print QByteArray.
.ex:
p bytes.d->data
define pqbytearray
set $i=0
while $i < $arg0.d->size
set $c = $arg0.d->data[$i++]
printf "%02x", $c
end
printf "\n"
end
----------------------------------------
gdb 中关闭下面的提示信息
---Type <return> to continue, or q <return> to quit---
----------------------------------------
set pagination off 即可.
这样,当你help all 时, 所有信息都会输出到屏幕, 方便你copy成文件再阅读!
-----------------------------------------
gdb 输出定向到文件
-----------------------------------------
1. 利用tee 命令全程跟踪记录gdb 的屏幕输出
gdb test | tee 1.log
2. 临时向文件输出信息, 例如想把info function 信息输出到文件.
set logging on
info functions
set logging off
------------------------------------------------------------
有关debug版, release版及调试信息,符号信息
------------------------------------------------------------
前言:
1. gcc -g 编译选项,生成debug 版, 有调试信息,
无-g, 生成release版, 无调试信息
2. strip -g 可以删除debug 信息
3. strip 默认删除所有与运行无关信息, 包括符号表,字符串表,调试相关信息
甲. 删除符号表信息和debug 信息为执行文件瘦身
$ strip testdbg
乙. 提取debug 信息(下面任何一种均可), 提取的dbg文件仍然是个可执行elf文件
$ objcopy --only-keep-debug testdbg strip.dbg
$ strip --only-keep-debug testdbg -o strip.dbg
丙. debug 信息的使用
1:命令行参数指定
a. 载入debug信息文件分析coredump
b. 载入debug信息文件调试程序, 两种指明文件方式可以混用.
$ gdb -e test-striped -c core -s strip.dbg
$ gdb -exec=test-striped -core=core -symbol=strip.dbg
2 还可以动态加载符号表文件:
(gdb) add-symbol-file FILE ADDR
(gdb) h add-symbol-file有更详细介绍.
使用稍微麻烦一点, 还要指定 .text 段地址ADDR, 也有可能需要指定其它段地址.
------------------------------------------------------------
gdb 使用相关
------------------------------------------------------------
查询调试文件信息及函数信息 (需要debug 信息)
(gdb) info source
Current source file is ioputs.c
Compilation directory is /build/eglibc-SvCtMH/eglibc-2.19/libio
Source language is c.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
(gdb) info sources (glibc 加debug后, 有大量源文件信息!!!)
(gdb) info functions (glibc 加debug后, 有大量函数信息!!!)
设置GDB 代码搜索路径
(gdb) set substitute-path /build/eglibc-SvCtMH/ /build/buildd/
(gdb) show substitute-path
(gdb) dir bak
./a.cpp变成了./bak/a.cpp
(gdb) show dir
多个源文件,gdb时如何在指定的某个文件中设置断点
(gdb) break [<file-name>:]<func-name>
(gdb) break [<file-name>:]<line-num>
-------------------------------
如何关闭gdb的彩色输出
-------------------------------
set style enabled off
只所以有这个需求, 是因为我用vim下gdb插件调试,其彩色输出被vim窗口显示成ascii 码,
如下图, 严重影响显示效果. 而关掉彩色输出, 世界就干净了!
qp_table_buf = ^[[34m0x0^[[m,
hw_frames_ctx = ^[[34m0x0^[[m,
opaque_ref = ^[[34m0x0^[[m,
但如果在控制台下使用gdb, 则带彩色会很好.
--------------------------------------------------------------------
将gdb调试限制为一次只能调试一个线程的处理方法
--------------------------------------------------------------------
需求:
我有多个线程,但我想调试一个线程,同时保持其它线程停止。 这样我能够观察这一个线程的表现(单步,下一步)
set scheduler-locking on
--------------------------------------------------------------------
跳过断点N次后再中断
--------------------------------------------------------------------
(gdb) h ignore
Set ignore-count of breakpoint number N to COUNT.
Usage is `ignore N COUNT'.
例如: 忽略6号断点100次
ignore 6 100
--------------------------------------------------------------------
gdb 查看加载的共享库信息
--------------------------------------------------------------------
(gdb) info sharedlibrary
--------------------------------------------------------------------
gdb 查看当前的pc值
--------------------------------------------------------------------
(gdb) p $pc
$pc 是与cpu无关的通用名称。
在x86_64cpu上,也可以用 p $rip
--------------------------------------------------------------------
gdb 脚本中的注释, 用 # 来注释.
--------------------------------------------------------------------
Make breakpoint pending on future shared library load? (y or [n]) [answered N; input not from terminal ]
--------------------------------------------------------------------
我们在脚本里下的断点很可能最开始还没载入,会出现找不到的情况. 此时gdb 默认给我们回答了No, 怎样让GDB 默认回答Yes 呢? 就是加载动态库后,在动态库设置断点 ?
set breakpoint pending on
在设置断点前加上以上设置即可!
--------------------------------------------------------------------
常用而又记不住的命令, 留此备份
set style enabled off //关闭gdb彩色输出
set max-value-size unlimited //设置gdb打印变量的最大尺寸无限制
set print elements ulimited // 设置gdb 打印字符串的长度无限制
set env LD_PRELOAD=/home/hjj/bin/libpreload_udpsend.so //设置环境变量举例
#set non-stop off //当线程遇断点中断时,其它线程是否中断
#set detach-on-fork off //多进程处理
#set follow-fork-mode child //多进程 跟踪哪个
#set scheduler-locking on //多线程其它线程的处理
#set breakpoint pending on //设置gdb断点可以推迟加载
----------------------------------------
用 gdb 重设pc 到指定行?
----------------------------------------
举例: 先用info line 查找行对应的pc 地址, 重设pc地址来完成
(gdb) info line 2910
Line 2910 of "libavformat/mpegts.c" starts at address 0x7ffff7d8de40 <sdt_cb+553> and ends at 0x7ffff7d8de48 <sdt_cb+561>.
(gdb) set $pc=0x7ffff7d8de40
这样实现了$pc 值强制改动.
方便,灵活, 要求你知道你在干什么!