Ошибка сегментации при открытии / закрытии файла? - PullRequest
0 голосов
/ 20 февраля 2012

Я работаю над многопоточной программой.Он в состоянии правильно закрыть все потоки, однако в конце он работает с ошибками.Закомментировав некоторые части моего кода, я обнаружил, что именно в этой области кода происходит открытие / закрытие файла:

char *pid_fname;
FILE *file;

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

/* code */

fclose(file);

Я попытался отладить в GDB, однако я получаю это только послераспечатка «где» после сегфоута:

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

Может кто-нибудь дать мне несколько советов о том, куда идти дальше?

Ответы [ 3 ]

3 голосов
/ 20 февраля 2012

У вас нет резервного хранилища для имени файла.Вы создали указатель, но не выделили место.Это означает, что он почти наверняка указывает куда-то, куда вы не хотите писать: -)

Предполагая, что вы знаете максимальный диапазон идентификатора процесса (скажем, 5 цифр, например), самое простое исправление - это что-то вроде (и немного изменив аргументы, поскольку /proc/ и /stat являются фиксированными строками):

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

В противном случае вам потребуется динамически распределять достаточно места на основе фактического значения pid и кодировать с защитойесли у вас не хватит памяти.

Поскольку системы обычно имеют фиксированный диапазон идентификаторов процессов, я бы выбрал буфер фиксированного размера.Если вы действительно хотите защитить от ошибок, не беспокоясь о динамическом размещении, вы можете использовать что-то вроде:

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);
3 голосов
/ 20 февраля 2012

sprintf требует, чтобы его первый аргумент был указателем на выделенный вызывающим буфер.Вы даже не инициализируете pid_fname.

1 голос
/ 20 февраля 2012
char *pid_fname;
sprintf(pid_fname, "%s%d%s", "/proc/", pid, "/stat");

pid_frame - неинициализированный указатель.В этом случае предоставленные аргументы не могут быть скопированы в буфер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...