izard: (Default)
izard ([personal profile] izard) wrote2021-08-09 09:38 pm
Entry tags:

My stupid bug, again

I just lost several hours today debugging the following:

I am linking to a library that has a function declared in a header as:
MACRO_EXPANDING_TO_RETURN_TYPE create_object_pointer(uint64_t* arg1, int arg2, int arg3);

I can’t include the corresponding header, so just cut&pasted the function declaration before use as:
extern
MACRO_EXPANDING_TO_RETURN_TYPE create_object_pointer(uint64_t* arg1, int arg2, int arg3);

Then I was calling it in my code:
return another_lib_func (create_object_pointer(arg1, arg2, arg3), “PASSING RESULT FROM lib_func");

another_lib_func is:
int another_lib_func(RETURN_TYPE t, String s)
{
If (t == NULL) return -1;
If (t->value < 0) return -1;
….
}

It segfaulted in another_lib_func, at second line. Why?

When I started debugging, I stepped into assembly of create_object_pointer and found that it created an object and returns its pointer.
Then I found that the pointer is truncated to 32 bits before being passed as a first argument to another_lib_func

This happened because MACRO_EXPANDING_TO_RETURN_TYPE expanded to an empty line in my compilation (I could not include the original header that redefined it properly, and generic project header defines it as empty.) So the compiler assumes create_object_pointer returns int,
which is int32_t, and truncates the 64 bit pointer.

So as it happens very often with nasty bugs in C code, preprocessor is involved, but it is not directly a root cause.

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting