DEV Community

Discussion on: I'm an Expert in Memory Management & Segfaults, Ask Me Anything!

 
codemouse92 profile image
Jason C. McDonald

You must remember that undefined behavior is exactly that. It may appear to work, and then not work elsewhere. When it doesn't work, anything could happen, including "making demons fly out your nose". So, I'd start by going through that Valgrind output, bit by bit, and fixing each problem in your code it highlights. (The error and location of that error in your code is on the last line of each traceback block in Valgrind.)

Once your //own// code runs Valgrind pure, we can tackle any remaining weirdness.

Thread Thread
 
kyrlon profile image
kyrlon

After furious placements of std::cout everywhere, I discovered that my function that my thread was calling was missing its return statement. Not sure how my first system was able to bypass that issue but it arised on my second system.

Thread Thread
 
codemouse92 profile image
Jason C. McDonald

So, it's resolved, then?

Thread Thread
 
kyrlon profile image
kyrlon

The issue yes. My curiosity, not so much lol. It shouldn't have compiled however that behavior I believe isactually allowed, it's grandfathered in from C. Since the function returns a variable and a return is not explicitly called then the first value in the stack frame is reinterpreted as the return type and returned instead

int foo(int bar) {
int blah= 8;
blah += 4;
int zayxxy = 0;
} //returns 12

So I believe that is the reason how my first system was able to execute without any problems. However, I do not fully understand how on the second system the function was never able to terminate the function but stay stuck in a while loop and result in a segfault.

Thread Thread
 
codemouse92 profile image
Jason C. McDonald • Edited

What you described, not returning a value from a non-void function, is actually undefined behavior in C. Therefore, once again, it is legal for the compiler to make demons fly out your nose. Anything can happen. There is no rhyme or reason.

Here's C99 on it — ISO/IEC 9899:1999, section 6.9.1 paragraph 12:

If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

One system's compiler was able to figure it out anyway, and it worked, which is legal (because anything is). The other system's compiler was not, and it had a snit.

P.S. Thanks for asking! I learned something new today, namely that the above is undefined behavior.

Thread Thread
 
kyrlon profile image
kyrlon

Glad I could help! I have definitely learned alot from this experience as well!

Thread Thread
 
ac000 profile image
Andrew Clayton

OK, firstly, a small nitpick, you weren't getting a segfault (SIGSEGV) but a SIGABRT

As for failing to return a value from a non-void function, you should at the very least compile with -Wall, which would have caught that. e.g

/* n.c - no return from non-void function */

static int test(void)
{
}
$ gcc -c n.c
$

vs

$ gcc -Wall -c n.c
n.c: In function ‘test’:
n.c:5:1: warning: no return statement in function returning non-void [-Wreturn-type]
    5 | }
      | ^
At top level:
n.c:3:12: warning: ‘test’ defined but not used [-Wunused-function]
    3 | static int test(void)
      |            ^~~~
$

And of course we also get the second warning...

I always compile with at least '-Wall -Wextra'