C++文件搜索程序触发SIGSEGV段错误,求问题排查及GDB使用方法
错误原因
- 字符串初始化错误:初始化
std::vector<std::string>时手动添加了多余的\0,std::string本身会自动维护终止符,手动添加会导致字符串长度计算异常,后续字符串匹配、比较操作都会出现未定义行为,甚至越界访问。 - 栈数组未初始化非法操作:
search_file_content函数中定义的变长数组char content[f_size]不仅不符合C++标准(属于GCC扩展特性),且未初始化就调用strcat。strcat要求目标字符串必须以\0结尾,未初始化的栈内存值是随机的,直接调用会导致越界写栈,破坏栈上存储的vector对象的this指针等关键数据,进而在调用size()方法时触发段错误。 - 字符串内存分配缺字节:
sub_array函数分配内存时仅申请了end - start字节的空间,没有预留字符串末尾\0的位置,返回的不是合法的C风格字符串,后续调用strcasecmp、strcpy等函数时都会越界访问。 - 内存释放不匹配:
format_filepath函数用new分配的路径内存,后续调用free释放,new必须对应delete、malloc对应free,释放方式不匹配会破坏堆内存结构,触发各种未定义行为。 - 固定长度数组越界风险:
format_filepath固定申请300字节存储路径、FileContent构造函数固定申请1000字节存储路径,遇到长路径时直接strcpy会直接越界写内存,破坏相邻的内存数据。 - 非法修改只读内存:
format_filepath中对entry->d_name调用strcpy修改其内容,而readdir返回的dirent结构体中的d_name属于只读内存区域,直接写入会直接触发段错误。
GDB排查具体步骤
- 重新编译程序时添加
-g参数保留调试符号,编译命令修改为:
g++ -g test_files_searcher.cpp -o files_searcher.out FilesSearcher_Linux/FilesSearcher.cpp FilesSearcher_Linux/FileContent.cpp
- 启动GDB加载程序:
gdb ./files_searcher.out - 运行程序触发段错误:在GDB交互界面输入
run命令启动程序,崩溃后GDB会自动停住 - 查看完整调用栈:输入
bt full,可以看到完整的函数调用链,以及每个栈帧的参数、局部变量值,确认是哪个vector对象调用size()时出错,以及对应的this指针是否为非法值(比如0、随机无效地址) - 定位内存破坏点:如果确认是栈被破坏导致
vector指针非法,可以对可疑的数组地址设置写断点,比如watch *0xxxxxxx(替换为出错的vector对象的地址),程序运行时只要这个地址被修改就会停住,直接定位到写非法内存的代码行 - 单步调试验证:在可疑函数(比如
search_file_content、format_filepath)开头设置断点,命令为b 函数全路径名,比如b FilesSearcher::search_file_content,断点命中后用n命令单步执行代码,搭配p 变量名打印变量值,确认哪一步执行后变量值出现异常。
内容的提问来源于stack exchange,提问作者I_4m_Z3r0
相关产品推荐
相关产品推荐

