Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
396 views
in Technique[技术] by (71.8m points)

c - what is causing SIGSEV?

/*

learning from all the post - please correct me if i am wrong..

now it makes sense- if i remember it right, the stack is a fixed memory segment- allocated on program start up... while the virtual memory can be sized/resized programmatically using malloc, realloc, free... the struct pointer array -

long size = 10000000; struct foo *bar[size];

should have been allocated from heap - using malloc()... instead of just a fixed size stack (program text)

*/

This one SIGSEV's:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    struct foo {
        int x;
        char s[5];
    };

    long size = 10000000;
    struct foo *bar[size];

    long i = 0;
    while (i < size) {
        printf("%ld 
", i);
        i++;
    }
}

This one works - commenting out the struct foo pointer array:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    struct foo {
        int x;
        char s[5];
    };

    long size = 10000000;
    //struct foo *bar[size];

    long i = 0;
    while (i < size) {
        printf("%ld 
", i);
        i++;
    }
}

This one works - commenting our the while loop:

#include <stdio.h>
#include <stdlib.h>

int main(void) {

    struct foo {
        int x;
        char s[5];
    };

    long size = 10000000;
    struct foo *bar[size];

    long i = 0;

    while (i < size) {
        //printf("%ld 
", i);
        i++;
    }

}

/* what i really am trying to achieve is this... which SIGSEVS - ok thanks for all your replies i really appreciate it... - will look int stack overflow and use explore using heap memory-- thanks guys */

int main(void) {

struct foo {
    int x;
    char s[5];
};

long size = 10000000;
struct foo *bar[size];

long i = 0;
while (i < size) {
    bar[i] = (struct foo *) malloc(sizeof(struct foo));
    free(bar[i]);
    i++;
}
return EXIT_SUCCESS;

}

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
long size = 10000000;
struct foo *bar[size];

will create a very big array, which may cause stack overflow, and therefore your program receive the SIGSEV.

You should create this array dynamically:

struct foo *bar = malloc(size * sizeof(struct foo *));

Why does the program work normally if these is not any function call in main()?

The definition of foo will cause main() to have a large stack frame at runtime. If you does not call any function in main(), this large stack frame will not be actually allocated or accessed (the entrance code of main() only make sure that amounts of memory be reserved by manipulating some registers and memory cells); but if you call a function in main(), the calling itself will try to access some addresses in that main() stack frame, because of stack overflow, those addresses may not be valid, this will cause SIGSEV be sent.

If you disassemble and compare the working and not-working versions of this program, this would be obvious. You could also find it out by stepping through the instructions of not-working main() one by one.


Without function call in main():

0x00001ff0 <main+0>:    push   %ebp
0x00001ff1 <main+1>:    mov    %esp,%eax
0x00001ff3 <main+3>:    mov    %esp,%ebp
0x00001ff5 <main+5>:    sub    $0x2625a10,%esp
0x00001ffb <main+11>:   mov    %eax,%esp
0x00001ffd <main+13>:   leave  
0x00001ffe <main+14>:   ret  

Call exit() in main():

0x00001fe0 <main+0>:    push   %ebp
0x00001fe1 <main+1>:    mov    %esp,%ebp
0x00001fe3 <main+3>:    sub    $0x2625a28,%esp
0x00001fe9 <main+9>:    movl   $0x0,(%esp)    <==== This causes segfault.
0x00001ff0 <main+16>:   call   0x3000 <dyld_stub_exit>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...