zzxyz
zzxyz

Reputation: 2981

fsanitize with gcc causing unexpected early exit

I've got an error that isn't consistently reproducible where free() is called on an invalid heap pointer. Reducing this problem to "minimal" is fundamentally not possible with the code in question--(once I've done that, it's solved). I'm unable to spot any obvious problems (such as a potential case where calloc is never called, or a double free, etc...)

I believe valgrind would be a solve for this except that the performance impact will be too extreme (these are client->server calls with timeouts, and operations that are expensive to begin with...>4 seconds in some cases)

This leaves me with fsanitize=address, I believe? My experience so far with this has been...not great.

What I've got is two static libs and an executable that links with them. I've turned on fsanitize=address for all three of them. With -fsanitize=address, the code exits cleanly under the debugger during a very thoroughly tested and correct init routine (in the middle of a 256 byte memcpy into a 16 meg heap allocation--exit code 1).

Can anyone with practical experience using fsanitize provide me any tips on where the problem may lie? I'm using gcc/ld under cmake and the code is (fundamentally) C compiled with C++. Switching to clang is probably an option if that might improve things.

Typical compile command for a file:

"command": "/usr/bin/c++   -I. -I/home/redacted -fpermissive -g -g3 -fasynchronous-unwind-tables -fsanitize=address   
-std=gnu++11 -o core/CMakeFiles/nginx_core.dir/src/core/nginx.cpp.o -c /home/redacted.cpp",

Upvotes: 1

Views: 262

Answers (1)

zzxyz
zzxyz

Reputation: 2981

I'm just going to leave this here for future searchers having problems with fsanitize. tldr;--It worked. I had two fundamental problems:

  1. fsanitize was outputting thorough error information about the reason it was exiting. This was getting swallowed by nginx...and in our customized version of it getting redirected to an obscure log file. Not sure why under gdb I wasn't getting a debug break, but nevertheless...it was detecting a legit error. Key piece of info here: Setting a breakpoint in __asan_report_error will halt the program before exit so you can inspect your various frames.

  2. While the initialization routine is correct and heavily tested, as I mentioned, it does require its client to correctly allocate a (non-trivial) configuration structure. In this case, the structure was 1 byte short of complete, causing a 1 byte overread.

Upvotes: 1

Related Questions