use*_*621 8 macros gdb loops while-loop
define traverse
while(CONDITION)
if $start == 0
set $start = 1
print_node
print_rss_item
else
continue
print_node
print_rss_item
end
end
end
Run Code Online (Sandbox Code Playgroud)
如果程序完成,我需要什么条件来停止循环?
看看你的gdb脚本:
define traverse
while(CONDITION)
if $start == 0
set $start = 1
print_node
print_rss_item
else
continue
print_node
print_rss_item
end
end
end
Run Code Online (Sandbox Code Playgroud)
有几点需要注意:
gdb脚本(所谓的"调试器")和调试对象始终以切换模式运行:无论GDB SCRIPT RUN,调试对象都暂停并且没有运行,并且每当DEBUGGEE运行时,gdb脚本都会暂停而不是运行.
为什么会这样?这是因为每当调试对象处于暂停模式(读取"ptrace()"API及其各种选项:PEEKUSER,POKEUSER,PTRACE_CONT)时,调试器实际上可以干净地(并且内存一致地)读取调试对象的内存而不用担心腐败,因此它的所有变量值等.
当调试器没有运行时,即它执行"继续"操作,其中控制被传递给调试对象,调试对象因此可以继续运行并改变自己的内存,而不用担心被另一个进程错误地读取 - 因为它不能发生了.
那么我们如何知道调试对象何时结束?当"继续"失败时,gdbscript将无法继续运行.但是如果你设置一个没有任何断点的调试对象,那么执行gdb"run"命令就会发现调试对象连续运行,而gdb脚本没有机会执行.
如果您的脚本正在运行,那么调试对象处于STOP模式,反之亦然.如果调试对象通过调用exit()结束,则gdb脚本也不会运行.
例如:
defining the macro (inside .gdbinit file):
define myloop_print
set $total = $arg0
set $i = 0
while($i<$total)
set $i = $i + 1
print $i, $i
cont
end
end
Run Code Online (Sandbox Code Playgroud)
然后运行"gdb/bin/ls",接着是"break write"和"run -al",然后是"myloop_print 10000"(序列或顺序很重要),我们可以看到每次"写入"都会破坏gdbscript将打印出柜台.
最后执行的几行是:
Breakpoint 1, write () at ../sysdeps/unix/syscall-template.S:81
81 in ../sysdeps/unix/syscall-template.S
$40571 = 285
drwxrwxr-x 2 tthtlc tthtlc 4096 Feb 18 00:00 yocto_slide
[Inferior 1 (process 7395) exited normally]
$40572 = 286
The program is not being run.
(gdb)
Run Code Online (Sandbox Code Playgroud)
这清楚地表明,最后一个打印的计数器是286,即使我已指定10000作为限制.
在没有运行调试对象的情况下运行宏:
(gdb) myloop_print 10000
$40573 = 1
The program is not being run.
(gdb)
Run Code Online (Sandbox Code Playgroud)
我们可以看到gdbscript不会运行.
如果你执行"gdb/bin/ls"并后跟"myloop_print 10000"(假设宏在.gdbinit中定义),那么你将得到gdbscript运行完成10000循环 - 没有调试对象运行.
简单地无限循环。当程序完成时它将退出。
define traverse
while(1)
if $start == 0
set $start = 1
print_node
print_rss_item
else
continue
print_node
print_rss_item
end
end
end
Run Code Online (Sandbox Code Playgroud)