代码之家  ›  专栏  ›  技术社区  ›  Vi.

如何使gdb重复获取stacktrace?

  •  4
  • Vi.  · 技术社区  · 14 年前

    就像在

    for((;;)) { 
        gdb -batch -n -ex 'set pagination off' -ex 'thread apply all bt' ffplay_g `pidof ffplay_g` >> /tmp/qq;
    }
    

    但是更快,不需要每次重新加载gdb和符号?

    回溯需要由计时器进行,而不是通过触发一些断点。

    3 回复  |  直到 13 年前
        1
  •  2
  •   oers Alfian Busyro    13 年前

    使用系统睡眠,这个 gdb 命令应该做到这一点:

    shell sleep 1
    
        2
  •  1
  •   Vi.    14 年前

    按照评论的建议 If you want to stick with gdb, then why not script a gdb session? Your controller process can sleep for 50 ms, then wake up, send a ^C, t a a bt, c, and then go back to sleep. – Jeremy W. Sherman

    http://vi-server.org/vi/bin/gdbdriver.pl

    #!/usr/bin/perl -w
    
    use strict;
    use IPC::Open2;
    
    my $init = "run";
    my $command = "bt";
    my $delay = 1;
    
    my $need_int=0;
    
    $init = shift @ARGV;
    $delay = shift @ARGV;
    $command = shift @ARGV;
    
    die("Usage: gdbpriver.pl '' 0.1 'bt' gdb -q /path/to/proc 33344\n\tgdbdriver.pl init_command period_seconds backtrace_command startup_arguments\n") unless $ARGV[0];
    
    my $pid = open2(\*OUT, \*IN, @ARGV);
    
    print "pid=$pid\n";
    
    print IN "set pagination off\n";
    print IN "$init\n";
    
    while(<OUT>) {
        if (/Starting program:/) {
        $need_int=1;
        last;
        }
        last if /\(gdb\)/;
    }
    
    sub intr() {
        kill 9, $pid;
        exit(0);
    }
    $SIG{'INT'} = \&intr;
    sub spipe() {
        print "PIPE!\n";
    }
    $SIG{'PIPE'} = \&spipe;
    
    if($need_int) {
        kill 2, $pid;
    }
    
    for(;;) {
        print IN "$command\n"; # backtrace
        print IN "c\n"; # continue the program
        while(<OUT>) {
        last if /Continuing./;
        print;
        }
        select undef, undef, undef, $delay; # sorry, nanosleep fails
        print "INT\n";
        kill 2, $pid; # SIGINT to gdb to make it interrupt the program
    }
    
        3
  •  0
  •   Jeremy W. Sherman    14 年前

    附加、设置断点、在该断点上设置命令,其中包括 continue ,然后继续:

    $ gdb attach ffplay_g
    . . .
    (gdb) b symbol
    (gdb) comm 1
    > t a a bt
    > c
    > end
    (gdb) c
    

    如果你在问如何让gdb有规律地进入,那么,你可以先循环调用step,然后回溯,但是你不会非常快:

    (gdb) while 1
    (gdb) t a a bt
    (gdb) s
    (gdb) end
    

    如果你试图描述你的过程,这是错误的方式。查看gprof或(在mac os/ios下)shark。