我有一个程序,我使用调试标志编译,当我正常执行时运行正常,但不会在gdb中运行。
以下是我看到的摘要:
gdb --args myProgram various arguments
//some standard gdb output stuff here
run
Starting Program: /full/path/to/my/executable/myProgram various arguments
During startup program exited with code 1
我相信"在启动期间" part表示程序在调用main之前退出,但到目前为止,我还没有能够在失败之前设置断点。
b main
- 与之前相同的输出b _start
- 与之前相同的输出b _init
- 与之前相同的输出b exit
- 与之前相同的输出catch syscall exit_group
- 与之前相同的输出starti
- 没有这样的命令,因为我的gdb太旧了set disable-aslr on
- 没有这样的符号(此时这有点绝望,我不知道ASLR是否在这方面发挥作用)set stop-on-solib-events 1
- 输出相同catch load
- 未定义的捕获命令break *0
- (来自this answer的狡猾的黑客)与以前相同的输出(加上有关无效地址的消息)info file
- 要查看入口点地址,它与_start b std::terminate
- 无法找到符号我所知道的唯一一件事就是在main之前发生了静态存储的变量。所以我想我可以采取的方法是尝试识别静态变量初始化的所有位置并在那里设置断点。然而,这是一个很大的代码库,它依赖于很多共享库,而且很多都是非常混乱的,因为当编码标准完全不同时,很多都是在80年代编写的。我真的不想深入研究所有这些,特别是因为我的信心非常低,无论如何它实际上都会帮助我。
也许我不应该专注于在程序退出之前尝试设置断点。也许还有另一种方法可以找出(甚至猜测)导致它退出的原因。
程序在GDB中的运行方式与从命令行运行方式有何不同?
当程序在GDB之外正常运行时,看到此错误的常见原因是什么?
GDB是否有可能在尝试启动程序之前报告此问题?或者它实际上是在启动它而我所有打破的尝试都因某种原因而无法正常工作?
答案 0 :(得分:2)
您可能想查看https://sourceware.org/gdb/onlinedocs/gdb/Starting.html,以了解gdb下启动过程的详细信息。它可能涉及外壳程序或某些包装程序,并且您引用的错误消息表示该外壳程序/包装程序在执行实际的二进制文件之前已退出。例如,如果您使用sudo
在shell设置为/bin/false
和的系统帐户下启动gdb,则将参数传递给和不要set startup-with-shell off
,gdb会尝试使用/bin/false
将参数传递给您的二进制文件,这自然会失败,并且您将得到引用的确切消息,而不是程序正在执行。>
答案 1 :(得分:1)
我相信"在启动期间" part表示程序在调用main
之前退出
你必须在Windows上(值得一提的是,因为解决方案与Linux有很大不同)。
否:这意味着程序在完成初始化之前收到EXIT_PROCESS_DEBUG_EVENT
。通常这意味着kernel32.dll
对此过程的设置方式并不感兴趣,甚至连程序的单指令都没有运行。
您可以通过set debugevents 1
从GDB获得其他调试帮助。
答案 2 :(得分:0)
嗯,这不是一个完全答案,但它已经修复了#34;。
解决方案是试图向同事证明这个问题。众所周知,Murphy定律似乎在演示过程中被放大了,所以一旦有人看着我,我就无法重现错误。
我从来没有能够复制它,所以我猜它现在正在工作。我能想到的唯一一件事就是我在最后一次看到错误和我向同事演示之间重启了我的电脑。我一直在修改一些环境变量(虽然我以为我已经按照它的方式设置了所有内容),所以也许我搞砸了一些东西。
感谢大家的帮助。
答案 3 :(得分:0)
当我使用的gdb版本与我的编译器稍有不兼容时,就会出现此问题。
答案 4 :(得分:0)
[已解决] 涉及重定向的特殊情况。
我收到“在启动期间程序以代码 130 退出。”当我在程序运行后很好地 ^C 时,
是的,我的 .gdbinit 中有“handle SIGINT pass nostop noprint”,所以我可以破坏我的程序,就好像它没有在调试器中运行一样。
事实证明我没有中断正确的程序。
我运行了“gdb a.out”,设置了一个断点,然后“r [args] 2>&1 > tee output.log”,因为我想立即看到 stdout/stderr 输出但也想捕获它在 output.log 中,以防它过快地开始传输错误并超出我的终端回滚缓冲区。
当我点击 ^C 时,我正在向 tee 发送一个 SIGINT,而不是我在 gdb 中运行的程序。
当我使用简单的“-r [args] 2> output.log”重新运行我的程序并在另一个窗口中执行“tail -f output.log”时,我的 ^C 向我的程序发送了 SIGINT,然后我优雅地退出了。