Ошибка сегментации указателя спорадического стека разветвленного процесса

Я пытаюсь отладить процесс, который иногда дает сбой сегментации при доступе к указателю стека.

Процесс, используемый для сегфокальной ошибки перед первой строкой main () {
Теперь сегмент перешел в другое место по линии.

Если не произойдет сбой, процесс будет продолжать работать правильно до бесконечности.

Я предполагаю, что это связано с тем, как создается процесс:

pid_t COsAbstraction::Start(const uint32_t coreId, const char* argv[])
{
pid_t pid;
sigset_t mask;
sigset_t save;

/*
* Block SIGCHLD
*/
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
pthread_sigmask(SIG_BLOCK, &mask, &save);

pid = fork();
if(pid < 0)
{
_exit(false);
}
if (pid != 0)
{
// I am the parent
pthread_sigmask(SIG_UNBLOCK, &save, NULL);
return pid;;
}
// I am the child
// Replace myself with the desired process
execvp(argv[ 0 ],  const_cast<char**>(argv))

_exit(0);

}

Код сбоя (спорадический):

(gdb) disassemble
Dump of assembler code for function main:
0x0804c663 <main+0>:    lea    0x4(%esp),%ecx
0x0804c667 <main+4>:    and    $0xfffffff0,%esp
0x0804c66a <main+7>:    pushl  -0x4(%ecx)
0x0804c66d <main+10>:   push   %ebp
0x0804c66e <main+11>:   mov    %esp,%ebp
0x0804c670 <main+13>:   push   %edi
0x0804c671 <main+14>:   push   %esi
0x0804c672 <main+15>:   push   %ebx
0x0804c673 <main+16>:   push   %ecx
0x0804c674 <main+17>:   sub    $0x525a8,%esp
0x0804c67a <main+23>:   call   0x804a22e <__i686.get_pc_thunk.bx>
0x0804c67f <main+28>:   add    $0x6125,%ebx
0x0804c685 <main+34>:   mov    (%ecx),%eax
0x0804c687 <main+36>:   mov    %eax,-0x52578(%ebp)
0x0804c68d <main+42>:   mov    0x4(%ecx),%ecx
0x0804c690 <main+45>:   mov    %ecx,-0x5257c(%ebp)
0x0804c696 <main+51>:   movl   $0x0,-0x418(%ebp)
0x0804c6a0 <main+61>:   movl   $0x400,0x8(%esp)
0x0804c6a8 <main+69>:   movl   $0x0,0x4(%esp)
0x0804c6b0 <main+77>:   lea    -0x410(%ebp),%eax
0x0804c6b6 <main+83>:   mov    %eax,(%esp)
0x0804c6b9 <main+86>:   call   0x8049c4c <memset@plt>

(gdb) info registers
eax            0xf746d564       -146352796
ecx            0xf746d4e0       -146352928
edx            0xf746d500       -146352896
ebx            0x444a7ff4       1145733108
esp            0xf741af10       0xf741af10
ebp            0xf746d4c8       0xf746d4c8
esi            0x8050b30        134548272
edi            0x8049d90        134520208
eip            0x804c67a        0x804c67a <main+23>
eflags         0x210282 [ SF IF RF ID ]
cs             0x23     35
ss             0x2b     43
ds             0x2b     43
es             0x2b     43
fs             0x0      0

Этот код работает на 24-ядерном устройстве RedHat Linux 2.6.

Обновить:

Оказывается, сбои не связаны с процессом вызова!
Простой «привет мир» также вылетает, когда сотни раз из оболочки:

#include <stdio.h>
int main(int argc, char* argv[])
{
char a[100*1024];
a[0] = '1';
printf("Hello There!\n");
return 0;
}

Должен ли я отправить новый вопрос или изменить этот?

3

Решение

С-программа вылетает, потому что вы выходите из стека программы.

Дело в том, что переменная типа

char a[100*1024];

размещается в стеке, его размер ограничен, и когда вы указываете на начало массива, вы выходите из стека, если процесс.

Чтобы дать вам пример, я просто изменил код, потому что я на amd64, поэтому я имею

#include <stdio.h>
int main(int argc, char* argv[])
{
char a[12*1024*1024];
a[0] = '1';
printf("Hello There!\n");
return 0;
}

поэтому я пытаюсь поместить переменную 12 МБ в стек. Размер стека по умолчанию, как вы можете видеть, составляет 8 МБ, и когда я пытаюсь выполнить его, я получаю это:

ottavio@magritte:/tmp$ ulimit -s
8192
ottavio@magritte:/tmp$ ./x
Segmentation fault

Но если я увеличу размер стека, это будет работать

ottavio@magritte:/tmp$ ulimit -s 16384
ottavio@magritte:/tmp$ ./x
Hello There!
ottavio@magritte:/tmp$
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]