From a38cfd353d98ca35b44de3f11949437587d68e72 Mon Sep 17 00:00:00 2001 From: Xingyu Wang Date: Sun, 18 Dec 2022 16:45:58 +0800 Subject: [PATCH 1/2] R @chai001125 --- ...️ 7 pro tips for using the GDB step command.md | 41 ++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md b/translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md index ea398cd4a0..8073fbf1c6 100644 --- a/translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md +++ b/translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md @@ -7,10 +7,12 @@ [#]: publisher: " " [#]: url: " " -GDB 进入函数内部的 7 个命令 +GDB 的 7 个单步调试命令 ====== ->**调试器**是一个可以运行你的代码并检查问题的软件。[GNU Debugger][1](GBD)是最流行的调试器之一,在这篇文章中,我研究了 **GDB 进入函数内部的几个命令**,包含了 **`step` 命令**和其他几个**常见的 GDB 命令**。`step` 是一个被广泛使用的命令,但它有一些人们不太了解的地方,可能会使得他们十分困惑。此外,还有一些方法可以**在不使用 `step` 命令的情况下进入一个函数**,比如使用不太知名的 `advance` 命令。 +> 即使是复杂的函数,也有几种方法可以单步调试,所以下次在排除代码故障时,可以尝试一下这些 GDB 技术。 + +**调试器** 是一个可以运行你的代码并检查问题的软件。[GNU Debugger][1](GBD)是最流行的调试器之一,在这篇文章中,我研究了 GDB 的 `step` 命令和其他几种常见情况的相关命令。`step` 是一个被广泛使用的命令,但它有一些人们不太了解的地方,可能会使得他们十分困惑。此外,还有一些方法可以**在不使用 `step` 命令的情况下进入一个函数**,比如使用不太知名的 `advance` 命令。 ### 1、无调试符号 @@ -19,6 +21,7 @@ GDB 进入函数内部的 7 个命令 ``` #include + int num() { return 2; } @@ -27,13 +30,14 @@ void bar(int i) { printf("i = %d\n", i); } + int main() { bar(num()); return 0; } ``` -如果你在没有 调试符号 debugging sysbols 的情况下进行编译(即在使用 `gcc` 编译程序时上,没有写 `-g` 选项),然后在 `bar` 上设置一个断点,然后尝试在这个函数内使用 `step`,来单步执行语句。GDB 会给出一个 没有行号信息 no line number information 的错误信息。 +如果你在没有 调试符号 debugging sysbols 的情况下进行编译(LCTT 译注:即在使用 `gcc` 编译程序时没有写 `-g` 选项),然后在 `bar` 上设置一个断点,然后尝试在这个函数内使用 `step` 来单步执行语句。GDB 会给出一个 没有行号信息 no line number information 的错误信息。 ``` gcc exmp.c -o exmp @@ -50,9 +54,9 @@ i = 2 0x0000000000401168 in main () ``` -### 2、`stepi` 命令 +### 2、stepi 命令 -但是你仍然可以在没有行号信息的函数内部单步执行语句,但要使用 `stepi` 命令来代替 `step`。`stepi` 一次只执行一条指令。当使用 GDB 的 `stepi` 命令时,先做 `display/i $pc` 通常很有用,这会在每一步之后**显示** **程序计数器的值** program counter value 和**相应的** **机器指令** machine instruction : +但是你仍然可以在没有行号信息的函数内部单步执行语句,但要使用 `stepi` 命令来代替 `step`。`stepi` 一次只执行一条指令。当使用 GDB 的 `stepi` 命令时,先做 `display/i $pc` 通常很有用,这会在每一步之后**显示** 程序计数器 program counter 的值和**相应的** 机器指令 machine instruction : ``` (gdb) b bar @@ -84,7 +88,7 @@ $1 = 2 ### 3、复杂的函数调用 -在带调试符号的 `-g` 选项,重新编译示例程序后,你可以用 `main` 中的行号,在 `bar` 上设置断点,然后再单步执行 `bar` 函数的语句: +在带调试符号的 `-g` 选项,重新编译示例程序后,你可以使用行号在 `main` 中 `bar` 调用上设置断点,然后再单步执行 `bar` 函数的语句: ``` gcc -g exmp.c -o exmp @@ -105,7 +109,7 @@ num () at exmp.c:4 4 return 2; ``` -函数调用的参数需要在实际的函数调用之前进行处理,`bar()` 函数调用了 `num()` 函数,所以 `num()` 会在 `bar()` 被调用之前执行。但是,通过 GDB 调试,你怎么才能如愿以偿地进入 `bar()` 函数呢?你可以使用 `finish` 命令,并再次使用 `step` 命令。 +函数调用的参数需要在实际的函数调用之前进行处理,`bar()` 函数的参数是 `num()` 函数,所以 `num()` 会在 `bar()` 被调用之前执行。但是,通过 GDB 调试,你怎么才能如愿以偿地进入 `bar()` 函数呢?你可以使用 `finish` 命令,并再次使用 `step` 命令。 ``` (gdb) finish @@ -118,11 +122,10 @@ bar (i=2) at exmp.c:9 9 printf("i = %d\n", i); ``` -### 4、`Tbreak` 命令 +### 4、tbreak 命令 `tbreak` 命令会设置一个**临时断点**。如果你不想设置永久断点,那么这个命令是很有用的。举个例子🌰,你想进入一个复杂的函数调用,例如 `f(g(h()), i(j()), ...)`,在这种情况下,你需要一个很长的 `step/finish/step` 序列,才能到达 `f` 函数。如果你设置一个临时断点,然后再使用 `continue` 命令,这样就不需要以上的序列了。为了证明这一点,你需要像以前一样将断点设置在 `main` 的 `bar` 调用上。然后在 `bar` 上设置临时断点。当到达该临时断点后,临时断点会被自动删除。 - ``` (gdb) r Starting program: /home/ahajkova/exmp @@ -132,7 +135,7 @@ Breakpoint 1, main () at exmp.c:14 Temporary breakpoint 2 at 0x40113c: file exmp.c, line 9. ``` -在调用 `bar` 的时候遇到断点,并在 `bar` 上设置临时断点后,你只需要使用`continue` 继续运行直到 `bar` 结束。 +在调用 `bar` 的时候遇到断点,并在 `bar` 上设置临时断点后,你只需要使用 `continue` 继续运行直到 `bar` 结束。 ``` (gdb) continue @@ -141,9 +144,9 @@ Temporary breakpoint 2, bar (i=2) at exmp.c:9 9 printf("i = %d\n", i); ``` -### 5、`disable` 命令 +### 5、disable 命令 -类似地,你也可以在 `bar` 上设置一个正常的断点,然后执行 `continue`,然后在不再需要第二个断点时,使用`disable` 命令禁用这个断点,这样也能达到与 `tbreak` 相同的效果。 +类似地,你也可以在 `bar` 上设置一个正常的断点,然后执行 `continue`,然后在不再需要第二个断点时,使用 `disable` 命令禁用这个断点,这样也能达到与 `tbreak` 相同的效果。 ``` (gdb) b exmp.c:14 @@ -161,7 +164,7 @@ Breakpoint 2, bar (i=2) at exmp.c:9 (gdb) disable 2 ``` -正如你所看到的,`info breakpoints` 命令在 `Enb` 下显示为 `n`,这意味着这个断点已被禁用。但你也能在再次需要这个断点时,再启用它。 +正如你所看到的,`info breakpoints` 命令在 `Enb` 列下显示为 `n`,这意味着这个断点已被禁用。但你也能在再次需要这个断点时,再启用它。 ``` (gdb) info breakpoints @@ -179,7 +182,7 @@ breakpoint already hit 1 time breakpoint already hit 1 time ``` -### 6、`Advance` 命令运行程序到指定的位置 +### 6、advance 命令运行程序到指定的位置 另一个进入函数内部的方法是 `advance` 命令。你可以简单地用 `advance bar`,来代替 `tbreak bar ; continue`。这一命令会将程序继续运行到指定的位置。 @@ -196,7 +199,7 @@ bar (i=2) at exmp.c:9 9 printf("i = %d\n", i); ``` -### 7、`skip` 命令 +### 7、skip 命令 进入 `bar` 函数的另一种方式是使用 `skip num` 命令: @@ -222,7 +225,7 @@ Num Enb Glob File RE Function 1 y n n num ``` -如果不再需要 `skip`,可以禁用(稍后重新启用)或完全删除它。你可以添加另一个 `skip`,并禁用第一个 `skip`,然后全部删除。要禁用某个 `skip`,必须指定其编号(例如,`skip disable 1`),如果没有指定,则会禁用所有的 `skip`。启用或删除 `skip` 的工作原理相同: +如果不再需要 `skip`,可以禁用(并稍后重新启用)或完全删除它。你可以添加另一个 `skip`,并禁用第一个 `skip`,然后全部删除。要禁用某个 `skip`,必须指定其编号(例如,`skip disable 1`),如果没有指定,则会禁用所有的 `skip`。启用或删除 `skip` 的工作原理相同: ``` (gdb) skip bar @@ -236,9 +239,9 @@ Num Enb Glob File RE Function Not skipping any files or functions. ``` -### GDB 的 `step` 命令 +### GDB 的 step 命令 -使用 GDB 的 `step` 命令是调试程序的一个有用工具。即使是复杂的函数,也有几种方法可以进入这些函数,所以下次你在排除代码问题的时候,可以尝试一下这些 GDB 技术。 +使用 GDB 的 `step` 命令是调试程序的一个有用工具。即使是复杂的函数,也有几种方法可以单步调试这些函数,所以下次你在排除代码问题的时候,可以尝试一下这些 GDB 技术。 -------------------------------------------------------------------------------- @@ -247,7 +250,7 @@ via: https://opensource.com/article/22/12/gdb-step-command 作者:[Alexandra][a] 选题:[lkxed][b] 译者:[chai001125](https://github.com/chai001125) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 From e550733f7b923ed02b2d491dbe24dfe70697e940 Mon Sep 17 00:00:00 2001 From: Xingyu Wang Date: Mon, 19 Dec 2022 09:39:23 +0800 Subject: [PATCH 2/2] P @chai001125 https://linux.cn/article-15362-1.html --- ...8.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) rename {translated/tech => published}/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md (97%) diff --git a/translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md b/published/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md similarity index 97% rename from translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md rename to published/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md index 8073fbf1c6..d864f7db50 100644 --- a/translated/tech/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md +++ b/published/20221208.2 ⭐️⭐️ 7 pro tips for using the GDB step command.md @@ -3,13 +3,15 @@ [#]: author: "Alexandra https://opensource.com/users/ahajkova" [#]: collector: "lkxed" [#]: translator: "chai001125" -[#]: reviewer: " " -[#]: publisher: " " -[#]: url: " " +[#]: reviewer: "wxy" +[#]: publisher: "wxy" +[#]: url: "https://linux.cn/article-15362-1.html" GDB 的 7 个单步调试命令 ====== +![][0] + > 即使是复杂的函数,也有几种方法可以单步调试,所以下次在排除代码故障时,可以尝试一下这些 GDB 技术。 **调试器** 是一个可以运行你的代码并检查问题的软件。[GNU Debugger][1](GBD)是最流行的调试器之一,在这篇文章中,我研究了 GDB 的 `step` 命令和其他几种常见情况的相关命令。`step` 是一个被广泛使用的命令,但它有一些人们不太了解的地方,可能会使得他们十分困惑。此外,还有一些方法可以**在不使用 `step` 命令的情况下进入一个函数**,比如使用不太知名的 `advance` 命令。 @@ -257,3 +259,4 @@ via: https://opensource.com/article/22/12/gdb-step-command [a]: https://opensource.com/users/ahajkova [b]: https://github.com/lkxed [1]: https://opensource.com/article/21/3/debug-code-gdb +[0]: https://img.linux.net.cn/data/attachment/album/202212/19/093831nrjrmozx1mixmgii.jpg \ No newline at end of file