在C程序中调用strace出现Seg fault段错误的解决方法求助
问题描述
我不想直接从命令行调用strace,希望编写一个C程序来为指定程序运行strace。我尝试解决该问题数小时仍未成功,此前我曾编写过一个模拟Shell行为并将用户输入记录到日志文件的程序。我提取了其中相关代码,修改为运行strace ls,但程序无法正常工作,且出现了Seg fault (core dumped)错误。以下是我的代码:
#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int main () { char *s = "strace ls"; char* separator = " "; char* argv[64]; int argc = 0; char* tmp; printf("%s", s); argv[argc] = strtok_r(s, separator, &tmp); while( argv[argc] != NULL){ argc+=1; argv[argc] = strtok_r(NULL, separator, &tmp); } execvp(argv[0],argv); return 0; }
问题分析与修复
你的程序触发段错误主要有两个核心问题:
修改只读字符串常量引发内存错误
你定义的char *s = "strace ls";是一个字符串常量,它被存储在进程的只读数据段中。而strtok_r函数会直接修改传入的字符串(用\0替换分隔符),尝试修改只读内存自然会触发段错误。解决方法:把字符串常量改成栈上的可修改字符数组:
char s[] = "strace ls";execvp要求参数列表以NULL结尾execvp的第二个参数是字符串数组,必须以NULL指针作为结尾标记,否则函数会超出数组范围访问内存,引发未定义行为(包括段错误)。解决方法:在填充完
argv数组后,添加结束标记:argv[argc] = NULL;
修正后的完整代码
#include <stdio.h> #include <unistd.h> #include <string.h> #include <stdlib.h> int main () { // 改为栈上可修改的字符数组 char s[] = "strace ls"; char* separator = " "; char* argv[64]; int argc = 0; char* tmp; printf("%s\n", s); argv[argc] = strtok_r(s, separator, &tmp); while( argv[argc] != NULL){ argc += 1; argv[argc] = strtok_r(NULL, separator, &tmp); } // 为execvp添加参数列表结束标记 argv[argc] = NULL; execvp(argv[0], argv); // 如果execvp执行到这里,说明调用失败,打印错误信息 perror("execvp failed"); return 1; }
额外加了perror调用,这样如果execvp执行失败(比如找不到strace命令),你能看到具体的错误原因,方便后续调试。
内容的提问来源于stack exchange,提问作者Leonard
相关产品推荐
相关产品推荐

