假设我有这个文件:
xb@dnxb:/tmp/c$ cat helloworld.h
void hello();
xb@dnxb:/tmp/c$ cat helloworld.c
#include <stdio.h>
void hello() {
printf("Hello world!\n");
printf("Next line\n");
}
xb@dnxb:/tmp/c$ cat main.c
#include <stdio.h>
#include "helloworld.h"
int
main(void) {
hello();
return 0;
}
编译:
xb@dnxb:/tmp/c$ gcc -g3 -shared -o libhello.so -fPIC helloworld.c -std=c11
xb@dnxb:/tmp/c$ gcc -g3 main.c -o main -Wl,-rpath,"$PWD" -L. -lhello
然后用gdb调试:
xb@dnxb:/tmp/c$ gdb -q -n ./main
Reading symbols from ./main...done.
(gdb) b main
Breakpoint 1 at 0x40062a: file main.c, line 5.
(gdb) r
Starting program: /tmp/c/main
Breakpoint 1, main () at main.c:5
5 hello();
(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
此时,反复按 Enter (相当于类型s
并反复按 Enter ):
(gdb)
_IO_puts (str=0x7ffff7bd9689 "Hello world!") at ioputs.c:33
33 ioputs.c: No such file or directory.
(gdb)
35 in ioputs.c
(gdb)
strlen () at ../sysdeps/x86_64/strlen.S:66
66 ../sysdeps/x86_64/strlen.S: No such file or directory.
(gdb)
如果我只关心helloworld.c
而没有进一步进入printf()
ioputs.c
以上的xb@dnxb:/tmp/c$ gdb -q -n ./main
Reading symbols from ./main...done.
(gdb) b main
Breakpoint 1 at 0x40062a: file main.c, line 5.
(gdb) r
Starting program: /tmp/c/main
Breakpoint 1, main () at main.c:5
5 hello();
(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
(gdb) n
Hello world!
4 printf("Next line\n");
(gdb)
该怎么办?
helloworld.c
这就是我想要的,但它需要我手动发现我在n
,现在是时候相应地输入(gdb) s
hello () at helloworld.c:3
3 printf("Hello world!\n");
了。我想要的是:
helloworld.c
按 Enter 将跳过自定义文件名的步入,例如在这种情况下printf("Next line\n");
,并直接跳至(gdb)
Hello world!
4 printf("Next line\n");
(gdb)
:
s
好处是我不必发现我应该停在哪里n
并更改为helloworld.c
,特别是如果代码层次结构很大并且我可能会步入<table class="w3-table-all w3-small w3-responsive">
<thead>
<tr class="w3-green">
<th style="padding:15px; font-weight:bold;">Departure Dates</th>
<th style="padding:15px; font-weight:bold;">Departure Availablity</th>
<th style="padding:15px; font-weight:bold;">Trip Cost</th>
<th style="padding:15px; font-weight:bold;">Inquiry</th>
</tr>
</thead>
<tr class="w3-hover-pale-green">
<td id="tripDate"><?=$ddate1='March, 21, 2017 - April, 06, 2017'?></td>
<td class="available">Available</td>
<td>USD$ 1250.00</td>
<td><a class="w3-btn w3-small w3-green w3-hover-green fancybox fancybox.iframe" href="<?=ROOTDIR.$_PHPLIB['contact']?>index.php?trpName=<?=$tripName?>&trpDate=<?=$ddate1;?>&trpUrl=<?=$actual_link;?>">Inquiry</a></td>
</tr>
<tr class="w3-hover-pale-green">
<td id="tripDate"><?=$ddate1='March, 28, 2017 - April, 13, 2017'?></td>
<td class="available">Available</td>
<td>USD$ 1250.00</td>
<td><a class="w3-btn w3-small w3-green w3-hover-green fancybox fancybox.iframe" href="<?=ROOTDIR.$_PHPLIB['contact']?>index.php?trpName=<?=$tripName?>&trpDate=<?=$ddate1;?>&trpUrl=<?=$actual_link;?>">Inquiry</a></td>
</tr>
<tr class="w3-hover-pale-green">
<td id="tripDate"><?=$ddate1='April, 04, 2017 - April, 20, 2017'?></td>
<td class="available">Available</td>
<td>USD$ 1250.00</td>
<td><a class="w3-btn w3-small w3-green w3-hover-green fancybox fancybox.iframe" href="<?=ROOTDIR.$_PHPLIB['contact']?>index.php?trpName=<?=$tripName?>&trpDate=<?=$ddate1;?>&trpUrl=<?=$actual_link;?>">Inquiry</a></td>
</tr>
</table>
时间。我只需要反复按 Enter 并跳过不需要的深度/等级。
我该怎么做?
答案 0 :(得分:1)
<强> [代码] 强>
我在我的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
的{{1}}的{{1}}是完整的文件路径)并编译它。但是失败了,它在source_info
的第一个步进中显示s->filename
而不是puts
,我不记得我做了什么,现在只更改为_IO_puts
:< / p>
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
hack)。现在使用gdb命令/tmp/gdbFile
使用常规Unix工具(set logging
/ shell
)解析文件,并将其重新格式化为grep
,然后使用gdb命令sed
设置变量:
/tmp/gdbFile.sources
<强> [4] 强>
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"
$
,则会调用此文件。 (只需在我的问题中将文件名/home/xiaobai/note/src/gdb-7.11.1/glibc-2.24/sysdeps/x86_64/strchr.S
更改为printf
以进行测试)
<强> [5] 强>
此代码使用文件路径中的空白空间进行测试,例如helloworld.c
<强> [6] 强>
如果我想排除大量文件路径,我很难扩展,因为我必须手动插入helloworld2.c
。如果您知道更好的方式,请发表评论。我也有点担心/tmp/c\ c/main
深度的递归可能会导致问题(我不确定gdb如何在内部处理它),所以我确保if-else-end
或if-esle-end
是最后一条指令条件。
<强> [7] 强>
幸运的是,在我运行n
后, Enter 不会更改为s
/ s
(n
的最后一条指令),即重复按 Enter 将保持行为sn
),否则我不知道如何分配它。
<强> [结果] 强>
从sn
按 Enter 进入sn
会自动将printf
更改为helloworld.c
,然后在返回后更改回s
从这个文件。请注意,我的自定义函数名为n
(如果没有其他命令名称以“my”开头,则s
应该正常工作)和mystartup
(不替换my
,因此您可以在sn
中间调用s
来执行:):
s
答案 1 :(得分:1)
GDB的skip命令可以让您跳过踩到不感兴趣的函数或文件。它的语法是跳过uninteresting_function 或跳过文件uninteresting.file 。 (完整文档here)
在您的情况下,您应该尝试跳过文件ioputs.c 。
Gdb 7.12在文件和函数名称上引入了模式,因此如果需要,您应该构建/安装该版本。此版本允许您(例如)跳过文件-gfi / lib / * ,它会跳过/ lib /...中的任何源文件。