代码之家  ›  专栏  ›  技术社区  ›  jhufford

图形初始化后,GDB在通过tcp进行远程调试时挂起

  •  0
  • jhufford  · 技术社区  · 6 年前

    我使用的是linux,正在尝试远程调试一个程序。

    我在目标上启动gdbserver,从.xinitrc

    gdbserver localhost:9134 /root/game/game
    

    在我的本地pc上(我在virtualbox虚拟机中运行),我通过以下命令从gdb连接到目标

    target remote 192.168.1.20:9134
    

    连接良好。 我可以用

    b main
    

    然后我可以继续,它会在那里破裂。我可以单步执行一个方法,直到它到达调用SDL\u Init(),从该调用它将永远不会返回gdb。 如果我不单步执行SDL\u Init,而是在程序中进一步设置一个断点,那么程序将正常启动并运行(因此它将通过SDL\u Init)。但是当它到达断点时,它在目标机器上冻结,并且本地机器上的gdb从不显示提示。整个系统挂起,必须重新启动。但是,它并没有完全冻结,因为鼠标指针仍然在目标上移动,您可以ping它,但是gdb连接不再工作。因此,似乎图形系统在某种程度上干扰了这一点,因为断点在图形系统init之前起作用,而不是之后。

    我试过设置 remotetimeout 设置为500秒,它表现出相同的行为。当我从本地pc ping远程目标时,报告的时间约为0.3到0.4毫秒,所以这看起来并不寻常,但我不排除我的其他任何错误配置的网络设置。

    它使用的是gdbserver版本6.8-19.fc10和gdb版本6.8-29.fc10的遗留系统(但是,它仍然赚钱)。升级版本,虽然是一个非常头痛的问题,可能是可能的,但可能不应该是必要的(我对我的电脑所做的任何升级也必须对州监管机构的系统进行,因为他们使用gdb设置进行测试,但这不是不可能的)。在我接手这个项目之前,远程调试已经开始工作了,现在还没有人来问我。gdbserver的版本绝对有效,因为我使用的是之前使用的程序。

    更新1:
    我将主机上的gdb版本更新为7.0.1版本,它仍然表现出相同的行为。我不能做8版,因为它需要一个C++ 11编译器和遗留系统是在那个时候。

    更新2:
    我在另一个虚拟机上尝试过这个,我甚至构建了一个新的专用linux安装(所以没有vm),重建了软件,我得到了相同的行为。因此,问题可能出在目标机器的配置上。

    更新3:
    我挖了一根串行电缆,最后通过串行接口得到了远程调试设置。它仍然不工作,但它给我更多的错误信息。我得到了错误

    gdbserver: error initializing thread_db library: version mismatch between libthread_db and libpthread
    

    我认为这是有意义的,因为我的断点在图形系统初始化后停止工作,这涉及到创建一些线程。在谷歌搜索了那个错误之后,我试着用 set solib-absolute-prefix , set solib-search-path ,和 set sysroot 到目标计算机上的文件系统副本的主机上的根目录(在主机上,即/fw\u dev/fgs/cf/initrd/expand,其中包含生成initrd的文件系统)
    但当我试图设置断点时 Error accessing memory address 0xb5eb60: Input/output error. 我也尝试过将这些变量设置到lib子目录,但也不起作用。我还尝试从主机的 /lib 目录到 /库 在目标上,但是x窗口甚至不能启动。

    更新#4:
    我尝试从主机上目标文件系统副本的根目录启动gdb(/fw\u dev/fgs/cf/initrd/expand),gdb仍然挂在断点上,但我不再收到关于libthread\u db和libpthread不匹配的错误消息,所以返回到绘图板。

    更新#5
    也许我应该问一个单独的问题,但我编译了gdb,然后自己运行了gbd。然后使用 file 要将其设置为主机上的程序,请设置远程目标,设置断点,然后运行 continue . 当我到达断点时,gdb一如既往地挂起。但是现在当我在gdb中按ctrl-c时,我得到了这个回溯

    #0  0x00110416 in __kernel_vsyscall ()
    #1  0x00b3f39d in ___newselect_nocancel () from /lib/libc.so.6
    #2  0x08203b9a in ser_base_wait_for (scb=0x96a2930, timeout=1) at ser-base.c:206
    #3  0x08203c89 in do_ser_base_readchar (scb=0x96a2930, timeout=-1) at ser-base.c:256
    #4  0x08204046 in generic_readchar (scb=0x96a2930, timeout=-1, do_readchar=0x8203c60 <do_ser_base_readchar>) at ser-base.c:326
    #5  0x082040b0 in ser_base_readchar (scb=0x96a2930, timeout=-1) at ser-base.c:391
    #6  0x081ecac2 in serial_readchar (scb=0x96a2930, timeout=-1) at serial.c:376
    #7  0x080c4357 in readchar (timeout=<value optimized out>) at remote.c:5922
    #8  0x080c5e35 in getpkt_or_notif_sane_1 (buf=0x839f140, sizeof_buf=0x839f144, forever=1, expecting_notif=0) at remote.c:6440
    #9  0x080d1e0a in getpkt_sane (ops=0x839f180, ptid=..., status=0xbffff388, options=0) at remote.c:6534
    #10 remote_wait_as (ops=0x839f180, ptid=..., status=0xbffff388, options=0) at remote.c:4736
    #11 remote_wait (ops=0x839f180, ptid=..., status=0xbffff388, options=0) at remote.c:4843
    #12 0x08184d4b in target_wait (ptid=..., status=0xbffff388, options=0) at target.c:2098
    #13 0x0815daf2 in wait_for_inferior (treat_exec_as_sigtrap=0) at infrun.c:2028
    #14 0x0815ddd4 in proceed (addr=4294967295, siggnal=TARGET_SIGNAL_DEFAULT, step=0) at infrun.c:1652
    #15 0x08153729 in continue_1 (all_threads=0) at infcmd.c:668
    #16 0x08153ea2 in continue_command (args=0x0, from_tty=0) at infcmd.c:760
    #17 0x0808e9e8 in execute_command (p=0x83b89a1 "", from_tty=0) at top.c:453
    #18 0x0816b028 in command_handler (command=0x83b89a0 "c") at event-top.c:511
    #19 0x0816bd5a in command_line_handler (rl=0x8ce83e8 "\340&\266\b\340\230\321\b") at event-top.c:736
    #20 0x0822d5a5 in rl_callback_read_char () at callback.c:205
    #21 0x0816b17b in rl_callback_read_char_wrapper (client_data=0x0) at event-top.c:178
    #22 0x0816ac54 in handle_file_event (data=...) at event-loop.c:812
    #23 0x08169e6b in process_event () at event-loop.c:394
    #24 0x0816aba4 in gdb_do_one_event (data=0x0) at event-loop.c:459
    #25 0x0816500b in catch_errors (func=0x816a950 <gdb_do_one_event>, func_args=0x0, errstring=0x82ccc3d "", mask=6) at exceptions.c:510
    #26 0x080f072a in tui_command_loop (data=0x0) at ./tui/tui-interp.c:153
    #27 0x08165684 in current_interp_command_loop () at interps.c:291
    #28 0x0808653b in captured_command_loop (data=0x0) at ./main.c:226
    #29 0x0816500b in catch_errors (func=0x8086530 <captured_command_loop>, func_args=0x0, errstring=0x82ccc3d "", mask=6) at exceptions.c:510
    #30 0x08085ecc in captured_main (data=0xbffff7a4) at ./main.c:902
    #31 0x0816500b in catch_errors (func=0x80853d0 <captured_main>, func_args=0xbffff7a4, errstring=0x82ccc3d "", mask=6) at exceptions.c:510
    #32 0x080851d1 in gdb_main (args=0xbffff7a4) at ./main.c:911
    #33 0x08085195 in main (argc=128, argv=0x0) at gdb.c:33
    

    所以gdb似乎挂在了内核vsyscall()中。正在进行差异化libc.so公司.6在主机的/lib目录中libc.so公司在目标上显示差异。我试过使用LD\u PRELOAD和LD\u LIBRARY\u PATH,但是回溯总是显示/lib/libc.so公司.6而不是指向目标具有的副本。也许我没有正确地设置它们,但是我试着用 set env 也可以在命令行上设置并导出它们,但没有效果。我还试着把libc从主机放到目标机器上,但它甚至无法启动,libc出现了一个错误。 那么如何让gdb加载不同的库呢?

    更新#6:
    所以我用目标系统的磁盘映像做了一个可引导的usb密钥。我对它做了最小的修改,使它能够在标准PC上运行,并向它添加了gdb和gdb必需的库。所以现在,ibc在主机和目标机器上都是一样的,它仍然挂在我的身上。

    最后。虽然我知道gdb6.8在过去工作过,但我不知道它的配置。升级后 二者都 gdb和gdbserver到7.12它工作了。

    0 回复  |  直到 6 年前
        1
  •  1
  •   Community CDub    5 年前

    升级版本,虽然是一个非常大的头痛,可能是可能的,但可能不应该是必要的。。。

    这是正确的选择。你遇到的所有其他问题都是因为这个。

    我在另一个虚拟机上尝试过这个,我甚至构建了一个新的专用linux安装(所以没有vm),重建了软件,我得到了相同的行为。因此,问题可能出在目标机器的配置上。

    您应该建立在与您试图将代码部署到的系统相同的版本、体系结构等之上。

    但是,当我尝试设置断点时,访问内存地址0xb5eb60时出错:输入/输出错误。

    this answer ,

    可能由32/64位混淆引起。例如,检查您没有附加到具有64位进程ID的32位二进制文件,反之亦然。

    我还试着把libc从主机放到目标机器上,但它甚至无法启动,libc出现了一个错误。

    别那么做。正如你所发现的,这是行不通的。

    那么如何让gdb加载不同的库呢?

    this question ,您可以使用 LD_LIBRARY_PATH .

        2
  •  0
  •   Ivan Kotov    6 年前

    Here are 一些有趣的建议。您是否尝试将gdbserver连接到strace以查看挂起期间正在进行的活动?正如其他人所说,这可能是一个很好的方法,可以更进一步地找出问题。 您可以在目标计算机上使用以下命令执行此操作:

    strace -p `pidof gdbserver`
    

    同时发送 CONT 发信号到 gdbserver 挂起时可能会有所帮助:

    kill -CONT `pidof gdbserver`