GDB远程调试中trace点收集变量显示<unavailable>的原因排查
问题
在GDB会话中使用trace定义跟踪点收集变量时,所有数据均显示<unavailable>,详细信息如下:
C代码
#include <stdio.h> int main() { // Define variables for square, cube, and the sums int square, cube; int sum_of_squares = 0, sum_of_cubes = 0; int i; // Loop from 1 to 10 for (i = 1; i <= 10; i++) { // Calculate square and cube of the current number square = i * i; cube = i * i * i; // Accumulate the sums sum_of_squares += square; sum_of_cubes += cube; } // After the loop, print the accumulated sums printf("Sum of squares: %d\n", sum_of_squares); printf("Sum of cubes: %d\n", sum_of_cubes); // Wait for the user to press any key before exiting printf("Press any key to exit...\n"); getchar(); // Wait for user input return 0; }
编译命令
gcc -g -O0 main.c -o test
调试操作步骤
- 启动gdbserver:
gdbserver :0 ./test # Process ./test created; pid = 70878 # Listening on port 43457
- 启动GDB并连接:
gdb -q ./test
- GDB会话指令:
(gdb) target remote :43457 (gdb) break main (gdb) continue (gdb) trace main.c:17 (gdb) actions # Enter actions for tracepoint 2, one per line. # End with a line saying just "end". # >collect square,cube # >end (gdb) tstart (gdb) continue ^C (gdb) tstop (gdb) tfind 0 (gdb) tdump # Data collected at tracepoint 2, trace frame 0: # square = <unavailable> # cube = <unavailable> (gdb) tfind # Found trace frame 1, tracepoint 2 # 17 sum_of_cubes += cube; (gdb) tdump # Data collected at tracepoint 2, trace frame 1: # square = <unavailable> # cube = <unavailable>
系统环境
mohammad@ubuntu:~$ uname -a Linux ubuntu 6.8.0-35-generic #35-Ubuntu SMP PREEMPT_DYNAMIC Tue May 21 07:52:29 UTC 2024 aarch64 aarch64 aarch64 GNU/Linux mohammad@ubuntu:~$ cat /etc/os-release PRETTY_NAME="Ubuntu 24.04.1 LTS" NAME="Ubuntu" VERSION_ID="24.04" VERSION="24.04.1 LTS (Noble Numbat)" VERSION_CODENAME=noble ID=ubuntu ID_LIKE=debian HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" UBUNTU_CODENAME=noble LOGO=ubuntu-logo mohammad@ubuntu:~$ gdb --version GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git Copyright (C) 2024 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. mohammad@ubuntu:~$ gcc --version gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0 Copyright (C) 2023 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. mohammad@ubuntu:~$ gdbserver --version GNU gdbserver (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git Copyright (C) 2024 Free Software Foundation, Inc. gdbserver is free software, covered by the GNU General Public License. This gdbserver was configured as "aarch64-linux-gnu" mohammad@ubuntu:~$ cat /proc/cmdline BOOT_IMAGE=/boot/vmlinuz-6.8.0-35-generic root=UUID=974aad07-eefd-4d23-a2c7-3c132d00c155 ro mohammad@ubuntu:~$
原因与解决方法
核心原因
跟踪点设置在main.c:17(sum_of_cubes += cube;)时,square变量在该行之后不再被使用,即使-O0编译级别,编译器也可能将其从内存中释放或复用寄存器;cube虽仍被读取,但也可能仅存于寄存器而非栈内存。GDB远程跟踪时无法直接访问寄存器中的临时数据,导致显示<unavailable>。
解决办法
调整跟踪点位置
将跟踪点移到square和cube仍处于活跃状态的行,比如main.c:15(sum_of_squares += square;):(gdb) trace main.c:15此时两个变量刚完成赋值且尚未被优化,GDB可以正常收集数据。
阻止编译器优化变量
修改C代码,给square和cube添加volatile关键字,强制变量存储在内存中:volatile int square, cube;重新编译后,跟踪点即使在原位置也能收集到变量值。
收集表达式值替代变量
不修改代码的前提下,直接收集表达式计算结果,绕开变量存储问题:(gdb) actions >collect i*i, i*i*i >endGDB会在跟踪点执行表达式计算并保存结果。
内容的提问来源于stack exchange,提问作者Mohammad Rahimi
相关产品推荐
相关产品推荐

