打开/关闭文件时出现分段错误?

时间:2012-02-20 05:26:06

标签: c multithreading file gdb

我正在开发一个多线程程序。它能够正确关闭所有线程,但最后会出现段错误。通过评论我的代码的某些部分,我发现它在代码的这个区域内处理打开/关闭文件:

char *pid_fname;
FILE *file;

sprintf(pid_fname, "%s%d%s", "/proc/", pid, "/stat");
file = fopen(pid_fname, "r");

/* code */

fclose(file);

我尝试在gdb中调试,但是我只在segfault之后打印出'where'后得到这个:

#0  0x2f312f63 in ?? ()
#1  0x74617473 in ?? ()
#2  0xbfaee700 in ?? ()
#3  0xbfaee77c in ?? ()
#4  0x006a7810 in ?? ()
#5  0x00000000 in ?? ()

任何人都可以给我一些关于从哪里开始的指示吗?

3 个答案:

答案 0 :(得分:3)

sprintf要求其第一个参数是指向调用者分配的缓冲区的指针。您甚至没有初始化pid_fname

答案 1 :(得分:3)

您没有文件名的后备存储空间。您已创建指针但未分配空间。这意味着它几乎肯定会指向你不想写的地方: - )

假设您知道进程ID的最大范围(例如5位数),最简单的修复就像(并且因为/proc//stat是固定字符串而略微更改参数):

char pid_fname[sizeof("/proc/99999/stat")];
sprintf(pid_fname, "/proc/%d/stat", pid);

否则,您需要根据实际pid值动态分配足够的空间,并在内存不足时进行防御性编码。

由于系统往往具有固定的进程ID范围,因此我选择固定大小的缓冲区。如果你真的想要防止错误,同时仍然不担心动态分配,你可以使用类似的东西:

char pid_fname[sizeof("/proc/99999/stat")];
if ((pid < 0) || (pid > 99999)) {
    fprintf (stderr, "WTH? What sort of PID was that (%d)?\n", pid);
    exit (1);
}
sprintf(pid_fname, "/proc/%d/stat", pid);

答案 2 :(得分:1)

char *pid_fname;
sprintf(pid_fname, "%s%d%s", "/proc/", pid, "/stat");

pid_frame是一个未初始化的指针。在这种情况下,提供的参数不能复制到缓冲区。