With reference to my previous question about GDB not pinpointing the SIGSEGV point,
My thread code is as follows:
void *runner(void *unused)
{
do
{
sem_wait(&x);
...
if(/*condition 1 check*/)
{
sem_post(&x);
sleep(5);
sem_wait(&x);
if(/*repeat condition 1 check; after atleast 5 seconds*/)
{
printf("LEAVING...\n");
sem_post(&x);
// putting exit(0); here resolves the dilemma
return(NULL);
}
}
sem_post(&x);
}while(1);
}
Main code:
sem_t x;
int main(void)
{
sem_init(&x,0,1);
...
pthread_t thrId;
pthread_create(&thrId,NULL,runner,NULL);
...
pthread_join(thrId,NULL);
return(0);
}
Edit: Having an exit(0) in the runner thread code, makes the fault vanish.
What could be the reasons behind the stack corruption?
GDB Output: (0xb7fe2b70 is runner thread id)
LEAVING...
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7fe2b70 (LWP 2604)]
0x00000011 in ?? ()
Valgrind Output:
==3076== Thread 2:
==3076== Jump to the invalid address stated on the next line
==3076== at 0x11: ???
==3076== by 0xA26CCD: clone (clone.S:133)
==3076== Address 0x11 is not stack'd, malloc'd or (recently) free'd
==3076==
==3076==
==3076== Process terminating with default action of signal 11 (SIGSEGV)
==3076== Bad permissions for mapped region at address 0x11
==3076== at 0x11: ???
==3076== by 0xA26CCD: clone (clone.S:133)
==3076== Address 0x11 is not stack'd, malloc'd or (recently) free'd
Write a new source file with a
mainfunction that does the same things as themainyou posted here except rather than usingpthread_createjust call the function. See if you can recreate the issue independent of using threads. From the way things look your semaphores should still work just fine in a single threaded environment.If this still fails you will have an easier time debugging it.
Since you said that calling
exitrather than returning did not yield the error it would suggest that you have corrupted either the return address that is on the stack whenrunneris started. By callingexityou don’t rely on this memory area to get to an exiting function (if you had returned pthread_exit would have been called by the pthread library code that had calledrunner). I think that the valgrind output is not 100% accurate — not due to any fault in valgrind, but because the place where you are triggering the error coupled with the type of error you are triggering makes this very difficult to be sure who called what.Some
gccflags you may be interested in:The warning option doesn’t work without the -f option here.
You may also want to try: