GDB使用strcmp与逻辑与运算符时触发"Invalid cast"错误
最近我在写C程序的时候,想用GDB设置条件断点或者打印变量值,但一用某些表达式就触发Invalid cast错误,折腾了好一会儿,先给你说说我的环境配置:
- OS: Ubuntu 24.04.1 LTS
- GCC: gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
- GDB: GNU gdb (Ubuntu 15.0.50.20240403-0ubuntu1) 15.0.50.20240403-git
- GLIBC: Ubuntu GLIBC 2.39-0ubuntu8.4
我的代码片段(未写完的部分应该包含相关逻辑)大概是这样的:
#include<stdio.h> // 推测你可能写了类似这样的逻辑,比如在条件里同时用strcmp和&& // #include<string.h> // char *my_str = "some_string"; // int counter = 0; // if (strcmp(my_str, "target") == 0 && counter > 3) { // // 业务代码 // }
然后在GDB里设置断点的时候,比如写了break main.c:12 if strcmp(my_str, "target") == 0 && counter > 3,就会弹出Invalid cast的错误。
问题原因
这个错误大概率是GDB在解析表达式时的类型推断出了问题——当你把字符串字面量直接传给strcmp,再和逻辑与运算符组合时,GDB可能错误地把字符串字面量当成了非指针类型,或者因为运算符优先级的问题,把表达式拆成了奇怪的类型组合,导致类型转换错误。
解决办法
给你几个亲测有效的方案:
给条件加括号明确边界
把每个判断条件用括号包起来,让GDB清晰识别每个条件的范围:break main.c:12 if (strcmp(my_str, "target") == 0) && (counter > 3)这样GDB就不会乱解析表达式的类型了。
用临时变量存strcmp结果
在代码里提前把strcmp的结果存到一个int变量里,再用这个变量写条件:#include<stdio.h> #include<string.h> // 别忘了加这个头文件! int main() { char *my_str = "test"; int cmp_res = strcmp(my_str, "target"); int counter = 5; if (cmp_res == 0 && counter > 3) { printf("Match!\n"); } return 0; }然后在GDB里直接用临时变量设置断点:
break main.c:9 if cmp_res == 0 && counter > 3完全绕开GDB对strcmp表达式的解析问题。
先用print命令验证表达式
设置断点前,先在GDB里用print命令测试你的表达式能不能正常运行:print (strcmp(my_str, "target") == 0) && (counter > 3)如果这个命令能正常返回布尔值,那直接用这个表达式设置断点就行;如果报错,就调整写法,比如加括号或者拆分条件,直到print能正常工作。
跳过GDB初始化脚本试试
有时候本地的.gdbinit脚本可能会干扰表达式解析,你可以用gdb -q启动GDB(不加载初始化脚本),再试试设置条件断点,看是否还会报错。
备注:内容来源于stack exchange,提问作者XuanCheng

