如何在程序完成之前循环GDB脚本?

时间:2013-12-09 22:04:25

标签: loops while-loop macros 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

如果程序完成,我需要在什么条件下停止循环?

2 个答案:

答案 0 :(得分:7)

查看你的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

有几点需要注意:

  1. gdb脚本(所谓的"调试器")和调试对象总是以切换模式运行:无论GDB SCRIPT RUN,调试对象都暂停而不运行,每当DEBUGGEE是正在运行,gdb脚本暂停而不是RUNNING。

  2. 为什么会这样?这是因为每当调试对象处于暂停模式时(读取" ptrace()" API及其各种选项:PEEKUSER,POKEUSER,PTRACE_CONT)调试器实际上可以干净地(并且内存一致地)读取内存调试对象,不用担心腐败,因此它的所有变量都是值等。

  3. 当调试器没有运行时,即它执行了"继续"操作,控制权传递给调试对象,调试对象因此可以继续运行并更改自己的内存,而不用担心被另一个进程错误地读取 - 因为它不会发生。

    那么我们如何知道调试对象何时结束?当"继续"失败,因此gdbscript不会继续运行。但是如果你设置一个没有任何断点的调试对象,那么执行gdb"运行"命令你会发现调试对象连续运行,而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
    

    然后运行&#34; gdb / bin / ls&#34;然后是&#34;打破写&#34;并且&#34; run -al&#34;然后&#34; myloop_print 10000&#34; (序列或顺序很重要),我们可以看到每一个&#34;写&#34;它将打破,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) 
    

    这清楚地表明,最后一个打印的计数器是286,即使我已指定10000作为限制。

    在没有运行调试对象的情况下运行宏:

    (gdb) myloop_print 10000
    $40573 = 1
    The program is not being run.
    (gdb) 
    

    我们可以看到gdbscript不会运行。

    如果你做&#34; gdb / bin / ls&#34;然后是&#34; myloop_print 10000&#34; (假设宏是在.gdbinit中定义的)然后你将得到gdbscript运行到完成10000循环 - 没有调试对象运行。

答案 1 :(得分:0)

简单地循环无限循环。程序结束后它将退出。

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