14

This function is buried in a complex nest so actually finding the cause is probably beyond anything I can ask, but I'm wondering if anyone might be able to give some tips on how I might go about debugging this. Here is the gist of the code I'm having trouble with

//func1.c
somestruct* func1(somestruct* mystruct)
{
    printf("func1: %p, %i\n", mystruct, mystruct->foo);
    return mystruct;
}
//func2.c
somestruct* func1(somestruct* mystruct);
void func2()
{
    somestruct *mystruct = malloc(sizeof(somestruct));
    mystruct->foo = 10;
    printf("func2: %p, %i\n", mystruct, mystruct->foo);
    mystruct = func1(mystruct);
    printf("back in func2: %p\n", mystruct);
    free(mystruct);
}

And I call func2. The output is like so

func2: 0x7f38a00008c0, 10
func1: 0x7f38a00008c0, 10
back in func2: 0xffffffffa00008c0
(SEGFAULT trying to free 0xffffffffa00008c0)

The actual code is more complex, "mystruct" gets passed around in many other places as well without issue, the fact that the functions are in different files seems like it might be part of the problem, yes it needs to return the pointer (the returned pointer is not guaranteed to be the same as the input pointer). It seems really weird to me that it's kind of (but not actually) getting truncated to 32 bits, and then filled with ffffffff at the top.

When compiled on a 32 bit machine it works exactly as it should.

I'd considered memory corruption somewhere, so I ran it through valgrind. Valgrind reports no errors, and in fact causes it to complete successfully. Textbook heisenbug. At least I can use GDB.

Does anyone have any idea what might be causing this, or at least how I might start tracking down the problem?

DavidG
  • 203
  • 1
  • 3
  • 6
  • 2
    This looks to me like a pointer being cast as as signed int (32-bit) and then cast back into a pointer. Bit 31 (sign bit of 32-bit int) is being extended into the high 32 bits. – DoxyLover Apr 17 '14 at 22:18
  • Are the files in the same project, compiled by the same makefile, with the same settings? What does func1 actually do? – Pod Apr 17 '14 at 22:53
  • func1 is exactly as written above at the moment, except as "tts_struct* get_utterance(tts_struct* utterance, char* text)". For testing purposes, it is ignoring everything that it used to do and just immediately returning the utterance it is given: output is the same. Yes, both files are in the same probject, same makefile, built as separate object files and then linked together at the end. – DavidG Apr 17 '14 at 22:56
  • 1
    You have a problem with your prototypes, func2() doesn't have the proper prototype for func1(). This does not show in the example code you post here ,so try to figure it out, or post the real deal. (also compile with warnings enabled.) – nos Apr 17 '14 at 23:36

1 Answers1

20

Check your code if you missed out function prototype (somestruct* func1(somestruct* mystruct);).in func2.c.

By default all return values are int. So if a prototype is missing for function then compiler treats the return value as 32-bit and generates code for 32-bit return value. Thats when your upper 4 bytes gets truncated.

Sasi V
  • 1,074
  • 9
  • 15