I'm trying to compile and run following program without main()
function in C
. I have compiled my program using the following command.
gcc -nostartfiles nomain.c
And compiler gives warning
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400340
Ok, No problem. then, I have run executable file(a.out), both printf
statements print successfully, and then get segmentation fault.
So, my question is, Why segmentation fault after successfully execute print statements?
my code:
#include <stdio.h>
void nomain()
{
printf("Hello World...\n");
printf("Successfully run without main...\n");
}
output:
Hello World...
Successfully run without main...
Segmentation fault (core dumped)
Note:
Here, -nostartfiles
gcc flag prevents the compiler from using standard startup files when linking
Let's have a look at the generated assembly of your program:
Note the
ret
statement. Your program's entry point is determined to benomain
, all is fine with that. But once the function returns, it attempts to jump into an address on the call stack... that isn't populated. That's an illegal access and a segmentation fault follows.A quick solution would be to call
exit()
at the end of your program (and assuming C11 we might as well mark the function as_Noreturn
):In fact, now your function behaves pretty much like a regular
main
function, since after returning frommain
, theexit
function is called withmain
's return value.In C, when functions/subroutines are called the stack is populated as (in the order):
main() being the start point, ELF structures the program in such a way that whatever instructions comes first would get pushed first, in this case printfs are.
Now, program is sort of truncated without return-address OR
__end__
and infact it assumes that whatever is there on the stack at that(__end__
) location is the return-address, but unfortunately its not and hence it crashes.