[代码]
我在我的 gdb 启动文件中编写了这段代码~/.gdbinit
(前 6 行是我编写这段代码之前的现有行):
set environment HISTSIZE 10000000
set history filename ~/.gdb_history
set history save on
set history size 10000000
set history expansion on
show history
#compile/make gdb failed
#rf: http://stackoverflow.com/a/33663513/1074998 #use `make install`
#rf: http://stackoverflow.com/a/15306144/1074998 #for step into strcpy(), memcpy()
#gcc -fno-builtin -g foo.c
#other rf: https://ubuntuforums.org/showthread.php?t=1572766
#rf: https://codywu2010.wordpress.com/2014/09/13/why-is-my-gdb-step-command-behavior-changed/
# printf step into 1st instruction is: _IO_puts (kali default gdb) vs puts (self-compile gdb)
#rf: http://stackoverflow.com/a/31076131/1074998
#nosharedlibrary, sharedlibrary
#rf: http://www.sourceware.org/gdb/onlinedocs/gdb/Source-Path.html #dir
#rf2: https://www.chemie.fu-berlin.de/chemnet/use/info/gdb/gdb_8.html #dir
#rf: http://stackoverflow.com/a/20116541/1074998
#`apt-get source libc6` and put the path of stdio-common (use `find . -name '*stdio-common*'` to find out)
dir '/home/xiaobai/note/src/gdb-7.11.1/glibc-2.24/stdio-common'
#rf: http://stackoverflow.com/a/29956038/1074998
dir '/usr/src/glibc/glibc-2.24/malloc'
set step-mode on
#rf: https://sourceware.org/gdb/onlinedocs/gdb/Define.html
#set max-user-call-depth 100000000
#type alias 'my' enough, nod ni type `mystart`
define mystart
#reset to fix "Value can't be converted to integer."
#initialized with enough buffer to fix "Too many array elements"
#`set {char [4096]}$fpath = 0` failed
#rf1: http://reverseengineering.stackexchange.com/a/2216/15176
#rf2: http://stackoverflow.com/a/30955291/1074998
#rf3: http://serverfault.com/a/306726/210566 ,and http://stackoverflow.com/a/14508945/1074998 #max file fullpath is 4096
set $fpath = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
set $dindex = 0
set $excludeFile="/tmp/c c/helloworld2.c"
set $excludeFile2="/home/xiaobai/note/src/gdb-7.11.1/glibc-2.24/sysdeps/x86_64/strchr.S"
#to ensure `set $fpath = $mallocFile` later will not truncate buffer
set $mallocFile = $fpath
#set it to "mallo.c" if not do `sudo apt-get install glibc-source`, `cd /usr/src/glibc`, `sudo tar xvf glibc-N.NN.tar.xz`, and put `dir '/usr/src/glibc/glibc-N.NN/malloc'` on top of this file, rf: http://stackoverflow.com/a/29956038/1074998
set $mallocFile = "/usr/src/glibc/glibc-2.24/malloc/malloc.c"
b main
r
end
#rf: http://stackoverflow.com/a/1530774/1074998
define pFullPathTitle
printf "\n******************** %s ********************\n", $fpath
end
define pFilePathTitle
printf "\n******************** <%s> ********************\n", $fpath
end
define sn
set $dindex += 1
echo \n[customStepping]\n\n
#rf: https://sourceware.org/gdb/onlinedocs/gdb/Logging-Output.html
set logging off
set logging file /tmp/gdbFile
set logging redirect on
set logging on
#ensure put this after `set logging on` otherwise will not work
set logging overwrite
#http://stackoverflow.com/a/1907066/1074998 #info source
#Bcareful might got extra headline "warning: Currently logging to /tmp/gdbFile. Turn the logging off and on to make the new setting effective."
#and line "^Located in " will not exist at all if no full filepath which was so common
info source
set logging off
#rf1: http://stackoverflow.com/a/6889615/1074998 #shell var to gdb
#rf2: http://unix.stackexchange.com/a/151609/64403 #eval
#rf3: http://www.delorie.com/gnu/docs/gdb/gdb_118.html #set var
#rf4: https://sourceware.org/gdb/download/onlinedocs/gdb/Convenience-Vars.html
#rf5: http://unix.stackexchange.com/a/320342/64403 #sed
shell echo 'set $fpath = "'`cat /tmp/gdbFile | grep '^Located' | sed 's/^Located in //g'`'"' > /tmp/gdbFile.sources
source /tmp/gdbFile.sources
#rf: https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html #if-else
#rf2: https://blogs.oracle.com/ksplice/entry/8_gdb_tricks_you_should #if
#rf: http://stackoverflow.com/a/7424716/1074998 #strcmp
if strcmp($fpath, $excludeFile) == 0
pFullPathTitle
echo File #1 [Stepping] Disabled \n
n
else
if strcmp($fpath, $excludeFile2) == 0
pFullPathTitle
echo File #2 [Stepping] Disabled \n
n
else
if strcmp($fpath, $mallocFile) == 0
#due to gdb freeze at this point, so i disable it #manually run no such problem, weird
# #2925 victim = _int_malloc (ar_ptr, bytes);
set $fpath = $mallocFile
pFullPathTitle
echo [mallo.c] freeze and should come here [Stepping] N/A\n\n
info source
#rf1: http://stackoverflow.com/a/9220953/1074998
#rf2: http://stackoverflow.com/questions/39124817/gdb-freezes-in-malloc
finish
#n
else
if strcmp($fpath, "") == 0
#`info source`'s "Located in " line not even exist !
#get single filename and set it to $fpath, source it, then print the title with this filename
shell echo 'set $fpath = "'`cat /tmp/gdbFile | grep '^Current source file is ' | sed 's/^Current source file is //g'`'"' > /tmp/gdbFile.sources
source /tmp/gdbFile.sources
pFilePathTitle
s
else
pFullPathTitle
s
end
end
end
end
end
[解释]
[1]
基本的想法是做n
而不是s
遇到我想跳过步进的文件完整路径。
[2]
“AAAAA ...”(4096个字符)字符串是我能找到的唯一方法,它可以$fpath
为完整文件路径保留内存,在程序运行之前需要动态更新。它可能有更好的处理方法,如果您知道更好的方法,请发表评论。
[3]
我的第一个问题是解析里面混合的完整文件路径info source
。我修改了 gdb 源代码(gdb/source.c
' source_info
ss->filename
是完整的文件路径)并编译它。但是失败了,它显示puts
而不是_IO_puts
在第一步中显示printf
,我不记得我做了什么,现在它变成了libc.so.6
:
(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
(gdb)
0x00007ffff788a160 in printf () from /lib/x86_64-linux-gnu/libc.so.6
(gdb)
0x00007ffff788a167 in printf () from /lib/x86_64-linux-gnu/libc.so.6
... `s->filename` still give me /tmp/c c/helloworld.c which is not what i want.
但在那之后我意识到我可以简单地将输出保存info source
到/tmp/gdbFile
第一个(使用set logging
黑客)。现在使用 gdb 命令使用常规 Unix 工具( / )shell
解析文件并将其重新格式化为,然后使用 gdb 命令设置变量:grep
sed
/tmp/gdbFile.sources
source
$ cat /tmp/gdbFile
warning: Currently logging to /tmp/gdbFile. Turn the logging off and on to make the new setting effective.
Current source file is main.c
Compilation directory is /tmp/c c
Located in /tmp/c c/main.c
Contains 7 lines.
Source language is c.
Producer is GNU C11 6.1.1 20160802 -mtune=generic -march=x86-64 -g3 -fno-builtin.
Compiled with DWARF 2 debugging format.
Includes preprocessor macro info.
$ cat /tmp/gdbFile.sources
set $fpath = "/usr/src/glibc/glibc-2.24/sysdeps/unix/sysv/linux/_exit.c"
$
[4]
/home/xiaobai/note/src/gdb-7.11.1/glibc-2.24/sysdeps/x86_64/strchr.S
是显示它可以禁用多个+任何文件名的示例。如果我启用 step into ,将调用此文件printf
。(只需在我的问题中将文件名更改为helloworld.c
进行helloworld2.c
测试)
[5]
此代码在文件路径中使用空白空间进行测试,例如/tmp/c\ c/main
[6]
如果我想排除很多文件路径,很难扩展,因为我必须手动插入if-else-end
. 如果您知道更好的方法,请发表评论。我也有点担心if-esle-end
深度递归可能会导致问题(我不确定 gdb 如何在内部处理它),所以我确保n
ors
是条件内的最后一条指令。
[7]
幸运的是,在我运行后Enter不会更改为s
/ n
(最后一条指令) ,即反复按将保持为),否则我不知道如何分配它。sn
sn
Entersn
[结果]
按Enterfrom printf
intohelloworld.c
会自动变为,从该文件返回后又s
变为。请注意,我的自定义函数被调用(如果没有其他命令名称以“my”开头,则应该可以正常工作)和(不替换,因此您可以在步进中间调用:):n
s
mystartup
my
sn
s
s
helloworld.c
xb@dnxb:/tmp/c c$ gdb -q /tmp/c\ c/main
expansion: History expansion on command input is on.
filename: The filename in which to record the command history is "/home/xiaobai/.gdb_history".
remove-duplicates: The number of history entries to look back at for duplicates is 0.
save: Saving of the history record on exit is on.
size: The size of the command history is 10000000.
Reading symbols from /tmp/c c/main...done.
(gdb) my
Breakpoint 1 at 0x40063a: file main.c, line 5.
Breakpoint 1, main () at main.c:5
5 hello();
(gdb) sn
[customStepping]
******************** /usr/src/glibc/glibc-2.24/sysdeps/unix/sysv/linux/_exit.c /tmp/c c/main.c ********************
hello () at helloworld.c:3
3 printf("Hello world!\n");
(gdb)
[customStepping]
******************** /tmp/c c/helloworld.c ********************
File #1 [Stepping] Disabled
Hello world!
4 printf("Next line\n");
(gdb)
[customStepping]
******************** /tmp/c c/helloworld.c ********************
File #1 [Stepping] Disabled
Next line
5 }
(gdb)
[customStepping]
******************** /tmp/c c/helloworld.c ********************
File #1 [Stepping] Disabled
main () at main.c:6
6 return 0;
(gdb)
[customStepping]
******************** /tmp/c c/main.c ********************
7 }
(gdb)
[customStepping]
******************** /tmp/c c/main.c ********************
__libc_start_main (main=0x400636 <main>, argc=1, argv=0x7fffffffd468, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffd458) at ../csu/libc-start.c:325
325 exit (result);
(gdb)
...