2014-08-18 6 views
2

Я получаю ошибку сегментации в следующей программе. Почему? И как его решить?ошибка сегментации в программе c в linux

#include <stdio.h> 
main() 
{ 
    int pid; 
    printf("I'm the original process with PID %d and PPID %d.\n", getpid(),getppid()); 
    pid=vfork(); 
    if (pid!=0) 
    { 
     printf("I'm the parent process with PID %d and PPID %d.\n",getpid(),getppid()); 
     printf("My child's PID is %d.\n", pid); 
    } 
    else 
    { 
     printf("I'm the child process with PID %d and PPID %d.\n",getpid(),getppid()); 
    } 
} 

Выход:

I'm the original process with PID 18563 and PPID 18500. 
I'm the child process with PID 18564 and PPID 18563. 
I'm the parent process with PID 18563 and PPID 18500. 
My child's PID is 18564. 
Segmentation fault 
+2

Это сработало для меня. Ошибка сегментации. –

+0

Отсутствие ошибки сегментации для меня тоже ... Это ваш код или просто упрощенный пример? – smagnan

+0

мужчина vfork. Важная деталь: «Ребенок не должен возвращаться из текущей функции или вызывать exit (3), но может вызывать _exit (2)». а также: «До этого момента ребенок разделяет всю память с родителем, включая стек». Случается, что возврат из основного дочернего элемента перемещает указатель стека. В зависимости от того, что произойдет дальше, вы получите SEGV у родителя или нет. В простом примере шансы всего хорошего – Ronald

ответ

4

vfork man page От

(от POSIX.1) Функция vfork() имеет тот же эффект, что и вилка (2), за исключением того, что поведение undefined, если процесс, созданный , vfork() либо изменяет любые данные, отличные от переменной типа pid_t , используемой для хранения возвращаемого значения из vfork(), или retu rns из функции , в которой был вызван vfork(), или вызывает любую другую функцию перед успешным вызовом _exit (2) или одного из семейства exec (3) функций .

Вы являются возвращение до того успешного вызова _Exit, поэтому такое поведение не определено. Попробуйте исправить это и посмотрите, не исчезла ли проблема.

+0

Вы были примерно на 10 секунд медленнее, чем я (я прокомментировал, не ответил), но примерно на 1 минуту быстрее, чем SzG :-). В любом случае, мы все согласны с тем, что использование vfork() только потому, что оно «быстрее» не является хорошей идеей, если вы не знаете ограничений. Я сделаю +1 вас обоих – Ronald

2

Цитата из человека странице vfork:

vfork() отличается от вилки (2) в том, что вызывающий поток приостанавливается, пока ребенок не прекращает (или нормально, позвонив по телефону _exit (2), или аномально, после доставки фатального сигнала), или он делает вызов execve (2). До этого момента ребенок разделяет всю память со своим родителем, включая стек. Ребенок НЕ ДОЛЖЕН ВОЗВРАТИТЬ ИЗ ТЕКУЩЕЙ ФУНКЦИИ или вызвать exit (3), но может вызвать _exit (2).

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

Смежные вопросы