【问题标题】:Attaching to gdb interupts and won't continue the process附加到 gdb 中断并且不会继续该过程
【发布时间】:2020-09-22 08:57:38
【问题描述】:

需要处理一些大型实时项目(多进程 (IPC),简称多一切)。

我正在处理的进程是作为 Linux 上的服务启动的。我有root访问权限。

问题出在这里:

我正在尝试附加到正在运行的 proc,尝试通过/使用 gdb 启动它,但结果是一样的:一旦我用 gdb“触摸”它就会停止可执行文件,或者有时它会抛出:

Program received signal SIGUSR1, User defined signal 1. [Switching to Thread 0x7f9fe869f700 (LWP 2638)]

当然,从那里什么也做不了。

试过了:

  1. 处理所有不停止
  2. 附加到作为服务(守护程序)启动或作为常规进程启动
  3. 从 gdb 开始
  4. 认为可能是分叉/多线程问题 - 在一开始就实现了 10 秒睡眠 - 用“继续”附加到它

伙计们,我想要的只是调试、命中断点等。

请帮忙!分享想法。

编辑实际命令:

1) gdb attach myProcId. 然后在读取符号后,我点击“c”,结果:

程序接收信号 SIGUSR1,用户定义信号 1。 [切换到线程 0x7f9fe869f700 (LWP 2638)] 0x00007f9fec09bf73 in select() from /lib64/libc.so.6

2) 如果我在代码中让第一行休眠 10 秒,附加到进程,点击“c”,结果:它运行,显示信息线程,main 的回溯,但从未命中断点(确保代码在那里运行 - 如果我在那里更改代码,我会得到日志和不同的行为),这意味着进程被卡住了。

3) 所有其他组合,如 gdb path/to/my/proc 参数列表,然后开始。其中 arg list 使用了 gdb 提供的不同相关选项。

也许值得一提:处理网络数据包相关,定时器也驱动。 但对我来说,重要的是当前的中断快照,我不在乎计时器到期后系统会发生什么。

【问题讨论】:

  • 我不确定我是否理解问题所在。您是说在 gdb 附加后您不能简单地在提示符处键入 continue 吗?您可能还想编辑您的问题以显示您用于附加的精确命令。
  • 你要附加的过程是什么?提供用于启动它的命令以及如何附加到它。
  • 调试器和断点不能很好地与多线程/多重处理混合,除非你能以某种方式停止一切。我学会了对代码进行桌面检查,和/或在必要时插入 printf()(或内核中的 printk())以获得显着的值或状态。如果你做对了,你就会学会不相信你的假设。
  • @sawdust 当然,日志很好。只是有时需要很长时间,添加 1 个打印,编译(在我的情况下需要 6 分钟),执行然后你意识到你需要有一些其他的值和回溯值。意味着退出,再次打印,编译....迭代耗时且令人沮丧的过程。取而代之的是,使用所有值(其中一些是可编辑的)来来回回进行调试可以节省数小时的“打印”工作。
  • 是的,修订-编译-测试周期可能很耗时。这就是为什么我写道你必须更聪明地工作,并检查代码是否存在缺陷。然后测试您的假设以确保您没有找到极端情况。继续并在一个单独的程序上使用断点。但是,如果您有一个与远程处理器交互的进程将恢复到某种恢复模式(即,如果您不能中断其他进程),那么 IMO 更好的选择是使用 printf() s。

标签: c++ c linux gdb embedded-linux


【解决方案1】:

既然你提到你正在调试一个多处理程序,我认为你的底层程序是在正确的子进程中设置断点。

试试break forkset follow-fork-mode child/parent。您想要实现的是将 gdb 附加到正在运行您要调试的代码的进程。 参考这个link

另一个想法是产生一个崩溃,因为你可以编译程序。例如添加一个int i = *(int*)NULL,这将生成一个核心转储。然后您可以使用gdb <program> <core dump> 调试核心转储。您可以参考此page 了解如何配置核心转储。

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多