gdb 调试不能显示全长字符串

本文介绍了解决GCC调试过程中字符串无法完全显示的问题。通过设置gdb中的print elements参数为0,可以取消字符串显示的最大字符数限制,从而完整查看字符串内容。

调试gcc时老是不能显示全字符串


(gdb) p cp->spec 
$35 = 0x8057080 "%{E|M|MM:%(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options)}      %{!E:%{!M:%{!MM:\t  %{save-temps:%(trad_capable_cpp) -lang-c %{ansi:-std=c89}\t\t%(cpp_options) %b.i \n\t\t    cc1 -fpreprocessed %"...

上网找无果,猜猜gdb中有一个值来控制显示多少吧?
直接看gdb源码,发现果然有.
可以使用set print elements命令来控制显示字符串最多字符数,默认是200.

(gdb) set print elements 0

(gdb) p cp->spec          

$36 = 0x8057080 "%{E|M|MM:%(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options)}      %{!E:%{!M:%{!MM:\t  %{save-temps:%(trad_capable_cpp) -lang-c %{ansi:-std=c89}\t\t%(cpp_options) %b.i \n\t\t    cc1 -fpreprocessed %b.i %(cc1_options)}\t  %{!save-temps:\t    %{traditional|ftraditional|traditional-cpp:\t\ttradcpp0 -lang-c %{ansi:-std=c89} %(cpp_options) %{!pipe:%g.i} |\n\t\t    cc1 -fpreprocessed %{!pipe:%g.i} %(cc1_options)}\t    %{!traditional:%{!ftraditional:%{!traditional-cpp:\t\tcc1 -lang-c %{ansi:-std=c89} %(cpp_options) %(cc1_options)}}}}        %{!fsyntax-only:%(invoke_as)}}}}"


转自:http://blog.chinaunix.net/uid-725631-id-3493.html

<think> 我们被要求用中文回答问题,并在最后提出3-5个相关问题,且第一行必须是“§§相关问题§§”且不能换行分散。 用户的问题是:gdb调试打印字符串 我们需要先回答gdb调试时打印字符串的方法,然后提出3-5个相关问题。 在GDB中打印字符串,通常使用`print`命令(缩写`p`)或者`x`命令。但是字符串在C/C++中可能是以字符数组、字符指针或者C++的std::string形式存在。因此,我们需要根据不同的类型采用不同的方法。 1. 对于C风格的字符串(字符数组或字符指针): 直接使用`print`命令,例如:`p (char*)0xaddress` 或者 `p *array@len`(如果知道长度)或者直接`p string_variable`(如果变量是字符指针或数组名)。 2. 对于C++的std::string: 由于std::string内部结构复杂,直接打印可能看不到字符串内容,可以使用: p string_variable.c_str() // 打印C风格字符串 或者,如果GDB支持,可以设置Python美化打印(需要GDB 7.0以上并且加载了libstdc++的pretty printers): p string_variable 3. 使用`x/s`命令:该命令可以检查内存并解释为字符串,例如:`x/s 0xaddress`。 4. 对于长字符串,可以使用`printf`命令(GDB 7.5以上)来格式化输出,例如:`printf "%s", string_variable`。 5. 设置打印选项:`set print elements 0`可以取消打印长度限制。 下面我们给出一个示例调试会话: 假设我们有以下C程序: ```c #include <stdio.h> #include <string.h> int main() { char *str1 = "Hello, GDB!"; char str2[20]; strcpy(str2, "Another string"); // C++程序的话,可能还有std::string,但这里用C示例 return 0; } ``` 编译:gcc -g test.c -o test 在GDB中: ``` (gdb) break main (gdb) run (gdb) p str1 $1 = 0x4005c4 "Hello, GDB!" (gdb) p str2 $2 = "Another string" (gdb) x/s str2 0x7fffffffe3a0: "Another string" ``` 如果遇到字符串被截断,可以使用: ``` (gdb) set print elements 0 (gdb) p str1 ``` 对于C++的std::string,假设有: ```cpp #include <string> int main() { std::string s = "Hello, std::string!"; return 0; } ``` 在GDB中: ``` (gdb) p s $1 = "Hello, std::string!" ``` 如果看不到字符串内容,可能是没有加载pretty printers,可以手动加载: ``` (gdb) source /usr/share/gcc-<version>/python/libstdcxx/v6/printers.py (gdb) p s ``` 现在,根据以上内容,我们总结回答: --- 在GDB调试中打印字符串的常用方法如下: ### 1. **C风格字符串** - **直接打印变量**:若变量为`char*`或字符数组,使用`print`命令: ```gdb (gdb) p char_ptr_var ``` - **指定内存地址打印**:用`x/s`命令查看内存中的字符串: ```gdb (gdb) x/s 0x4005c4 # 打印0x4005c4地址起的字符串 ``` - **打印部分内容**:若需截取长度,使用`@`符号: ```gdb (gdb) p *char_ptr_var@20 # 打印前20个字符 ``` ### 2. **C++ std::string** - **调用`.c_str()`方法**:转换为C字符串后打印: ```gdb (gdb) p str_var.c_str() ``` - **启用美化打印**(需加载libstdc++ pretty printers): ```gdb (gdb) source /path/to/libstdcxx-printers.py (gdb) p str_var ``` ### 3. **长字符串处理** - **取消长度限制**: ```gdb (gdb) set print elements 0 ``` - **格式化输出**(GDB≥7.5): ```gdb (gdb) printf "%s", char_ptr_var ``` ### 4. **动态内存字符串** 若字符串位于堆内存(如`malloc`分配),直接打印指针地址: ```gdb (gdb) p (char*)malloc_ptr ``` --- §§相关问题§§ 1. 在GDB中如何打印包含非打印字符(如换行、制表符)的字符串? 2. 调试时遇到字符串地址无效(如悬垂指针)应如何安全地检查内容? 3. 如何为自定义字符串类型(如结构体中封装的字符串)实现GDB美化打印? 4. 在GDB中能否实时修改字符串内存内容?具体步骤是什么? </think>### GDB调试中打印字符串的方法 在GDB调试器中打印字符串的常用命令及示例如下: #### 1. **基础打印命令** - **`print` / `p`**:直接打印变量或表达式 ```gdb (gdb) p (char*)str_ptr # 打印指针指向的字符串 (gdb) p global_str # 打印全局字符串变量 ``` - **`x/s`**:检查内存地址处的字符串 ```gdb (gdb) x/s 0x7fffffffe320 # 打印该地址的字符串内容 > 0x7fffffffe320: "Hello, GDB!" ``` #### 2. **特殊场景处理** - **打印截断字符串**(默认只显示前200字符): ```gdb (gdb) set print elements 0 # 关闭截断 (gdb) p long_str ``` - **打印非空终止字符串**: ```gdb (gdb) p {char[10]}buffer # 强制按长度打印 > {0x41, 0x42, ...} # 显示ASCII值 ``` #### 3. **结构化输出** - **打印STL字符串**(需加载libstdc++美化器): ```gdb (gdb) p std_str._M_data() # 直接访问底层指针 (gdb) p std_str # 自动美化输出 (需配置) > "C++ String" ``` - **格式化输出**: ```gdb (gdb) printf "%s\n", str_ptr # 类C语言格式化 ``` #### 4. **调试技巧** - **观察点监控字符串修改**: ```gdb (gdb) watch -l *(char(*)[20])&buf # 监控20字节缓冲区变化 ``` - **条件断点**: ```gdb (gdb) b foo.c:20 if strcmp(str, "target")==0 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值