如何在gdb中使用'target remote'重新运行程序?

39

当您在同一台计算机上对可执行文件进行常规gdb会话时,可以输入run命令来重新启动程序。

当您在嵌入式系统上运行gdb时,例如使用命令target localhost:3210,如何重新启动程序而不退出并重新启动gdb会话?

9个回答


11

很遗憾,我不知道如何重新启动应用程序并仍然保持您的会话。一种解决方法是将PC设置回程序入口点。您可以通过调用以下任一选项来执行此操作:

jump function

或者

set $pc=address

如果您修改了main函数的参数,则可能需要重新设置这些参数。

编辑:

上述方法存在一些注意事项可能会导致问题。

  • 如果您在多线程程序中跳转到主线程,则当前线程将跳转到主线程,而其他所有线程将保持原样。如果当前线程持有锁定...则会出现一些问题。
  • 内存泄漏:如果您的程序流在初始化期间分配了一些内容,那么使用跳转(jump)将会造成内存泄漏。
  • 打开的文件将仍然保持打开状态。 如果您mmap一些文件或地址,则该调用很可能会失败。

因此,使用jump并不等同于重新启动程序。


对于一个简单的非多线程应用程序,跳转正是我所需要的。 - wulfgarpro

5
“jump _start”通常是常规方式。

4

假设您正在嵌入式系统上运行gdbserver。

您可以使用 target extended-remote 命令要求它重新启动您的程序,而不是退出。


很有帮助,我不知道目标扩展模式。谢谢。 - sstock

3

步骤详解

远程:

# pwd contains cross-compiled ./myexec
gdbserver --multi :1234

本地:

# pwd also contains the same cross-compiled ./myexec
gdb -ex 'target extended-remote 192.168.0.1:1234' \
    -ex 'set remote exec-file ./myexec' \
    --args ./myexec arg1 arg2
(gdb) r
[Inferior 1 (process 1234) exited normally]
(gdb) r
[Inferior 1 (process 1235) exited normally]
(gdb) monitor exit

在Ubuntu 14.04上进行了测试。

还可以通过以下方式将CLI参数传递给程序:

gdbserver --multi :1234 ./myexec arg1 arg2

而且,./myexec 部分可以省略 set remote exec-file ./myexec 命令,但有以下缺点:

在不重启的情况下传递环境变量和更改工作目录:如何修改 gdbserver --multi 的环境变量和工作目录而无需重启?


3
对我来说,21.2 示例GDB会话启动中描述的方法非常好用。当我在“(gdb)”提示符下输入monitor reset halt后,目标硬件将被重置,并且我可以使用c(= continue)重新启动应用程序。
由于没有必要反复刷写程序,因此在运行之间可以省略load命令。

2
如果您正在运行常规的gdb,您可以输入“run”或“r”快捷键,gdb会询问您是否希望重新启动程序。

1
你可以使用jump gdb命令。为此,您可以检查您的startup脚本。 我的startup script有一个符号。
    .section  .text.Reset_Handler
  .weak  Reset_Handler
  .type  Reset_Handler, %function
Reset_Handler:  
   ldr   r0, =_estack
   mov   sp, r0          /* set stack pointer */

我想跳过开始部分。这就是我使用的代码:

jump Reset_Handler

0
在 EFM32 Happy Gecko 上,我尝试了所有的建议都不起作用,所以这里是我从将 GDB 集成到 Eclipse 环境的文档中学到的内容。
(gdb) mon reset 0
(gdb) continue
(gdb) continue

这使我处于从IDE重置时所期望的状态。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接