zig icon indicating copy to clipboard operation
zig copied to clipboard

zig cc -fsanatize=address fails at link time on macOS

Open drfuchs opened this issue 2 years ago • 9 comments

Zig Version

0.10.0-dev.1736+93e11b824

Steps to Reproduce

zig cc -fsanitize=address hello.c

Tried on "Apple M1 Pro macOS Monterey 12.3.1" as well as "Intel Core i7 macOS Catalina 10.15.7"

Expected Behavior

Joy in Mudville

Actual Behavior

zig cc -fsanitize=address hello.c error(link): undefined reference to symbol '___asan_init' error(link): first referenced in '/Users/elided/.cache/zig/o/elided/hello.o' error(link): undefined reference to symbol '___asan_register_image_globals' error(link): first referenced in '/Users/elided/.cache/zig/o/elided/hello.o' error(link): undefined reference to symbol '___asan_unregister_image_globals' error(link): first referenced in '/Users/elided/.cache/zig/o/elided/hello.o' error(link): undefined reference to symbol '___asan_version_mismatch_check_v8' error(link): first referenced in '/Users/elided/.cache/zig/o/elided/hello.o' error: UndefinedSymbolReference

(On macOS Monterey, it also first complained: warning(link): directory not found for '-L/usr/local/lib' for what that's worth.)

drfuchs avatar Apr 07 '22 14:04 drfuchs

This is related to #5163 and #10374 - although applying to asan instead of ubsan.

moosichu avatar Apr 12 '22 22:04 moosichu

(Just to add more color to this bug / lack of feature, in case it affects its prioritization:)

This issue interferes with Zig's "Maintain it with Zig: Incrementally improve your C/C++/Zig codebase" story.

Most directly, you can't use the advertised "drop-in C/C++ compiler" functionality of Zig for developing stand-alone C code while asan detection is crucial. So all the fabulous advantages of being able to do so disappear.

More importantly, it also seems to interfere with taking existing C codebases that are in pretty good but perhaps not immaculate condition, and trying to incrementally port them to Zig: How can I compile and link and run such that something is keeping an eye on the malloc'd pointers used by the C code at runtime, while still being able to call into / out of Zig code that's also compiled in debug mode? Or even if my C code is perfect, perhaps I might call it in an incorrect way from my new Zig code, causing the C code to, say, dereference a free pointer, which still needs detecting.

I'm willing to make any C-world pointer that round-trips through Zig code be a pointer to a type that's opaque to my Zig code (so that they never get dereferenced directly in the Zig code, and thus need no asan-like checking there), if that helps; or use something other than malloc/free from C; or whatever else might do the trick.

Or did I perhaps miss the boat, and there's a currently-supported way to handle this, perhaps using regular "cc -fsanitize=address" on the C code, and "zig build-obj" on the zig code, and who-knows-what linker to put it all together (and pray that there are no conflicts about who owns main() and whose crt startup code gets included and what libraries I have to explicitly include, and etc.)? Will the solution work across platforms, even ignoring cross-compilation?

FWIW, I'm way more concerned about asan than general ubsan detection, based on the difficulty of tracking down the bugs that result when not automatically detected at the moment of initial transgression.

drfuchs avatar May 09 '22 20:05 drfuchs

I'll link https://github.com/ziglang/zig/issues/12992 here since I feel its related - to fully support C++ in zigcc on all targets.

prenaux avatar Sep 29 '22 14:09 prenaux

Here is how Apple is driving it in their unit tests, https://github.com/apple-oss-distributions/libmalloc/blob/387a5a03c017801ecdfe9cbe7f8d69a9b427df68/tests/asan.c#L13

Another reason why it would be nice to have all of MacOS libsystem building statically, so Zig could re-use Apple's own tests.

chadbrewbaker avatar Dec 12 '22 22:12 chadbrewbaker

Reproducible on linux x86_64 so this is not a macos-specific issue:

 % ./zig-linux-x86_64-0.11.0-dev.2368+f4b411314/zig cc -fsanitize=address  hello.c
LLD Link... ld.lld: error: undefined symbol: __asan_init
>>> referenced by hello.c
>>>               /home/user/.cache/zig/o/35face62758b9eaf253cfae70bafbb87/hello.o:(asan.module_ctor)

ld.lld: error: undefined symbol: __asan_version_mismatch_check_v8
>>> referenced by hello.c
>>>               /home/user/.cache/zig/o/35face62758b9eaf253cfae70bafbb87/hello.o:(asan.module_ctor)

ld.lld: error: undefined symbol: __asan_register_globals
>>> referenced by hello.c
>>>               /home/user/.cache/zig/o/35face62758b9eaf253cfae70bafbb87/hello.o:(asan.module_ctor)

ld.lld: error: undefined symbol: __asan_unregister_globals
>>> referenced by hello.c
>>>               /home/user/.cache/zig/o/35face62758b9eaf253cfae70bafbb87/hello.o:(asan.module_dtor)

chrisirhc avatar Apr 03 '23 06:04 chrisirhc

I had the same issue on windows 11

Please note that, the same command works with clang but not zig cc.

# Will work
$ clang .\main.c .\pingpong.c -Wall -Wextra -Wpedantic -fsanitize=address -O0 -g3 -o .\appb.exe
   Creating library .\appb.lib and object .\appb.exp
# Will fail
$ zig cc .\main.c .\pingpong.c -Wall -Wextra -Wpedantic -fsanitize=address -O0 -g3 -o .\appb.exe
LLD Link... lld-link: error: undefined symbol: __asan_report_load1
[....]

Here's some info about my setup: image

g-berthiaume avatar Oct 13 '23 20:10 g-berthiaume

I had the same issue on windows 11

Please note that, the same command works with clang but not zig cc.

# Will work
$ clang .\main.c .\pingpong.c -Wall -Wextra -Wpedantic -fsanitize=address -O0 -g3 -o .\appb.exe
   Creating library .\appb.lib and object .\appb.exp
# Will fail
$ zig cc .\main.c .\pingpong.c -Wall -Wextra -Wpedantic -fsanitize=address -O0 -g3 -o .\appb.exe
LLD Link... lld-link: error: undefined symbol: __asan_report_load1
[....]

Here's some info about my setup: image

I just added -L$(ASAN_DIR) and -lasan to link flags, and now asan works. (Windows11, inside WSL2).

$ cat 1.cpp
#include <cstdio>

int main() {
    printf("Hello World!\n");
    new int;
    return 0;
}
$ find /usr/lib -type f -name "libasan.*"
/usr/lib/gcc/x86_64-linux-gnu/11/libasan.a
/usr/lib/x86_64-linux-gnu/libasan.so.6.0.0
$ zig c++ -L/usr/lib/gcc/x86_64-linux-gnu/11 -lasan -fsanitize=address -o zig_bin 1.cpp
$ ./zig_bin
Hello World!

=================================================================
==10112==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 4 byte(s) in 1 object(s) allocated from:
    #0 0x7f8a2046a1e7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99
    #1 0x201766 in main /mnt/c/W/cli/1/1.cpp:5
    #2 0x7f8a201b5d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)

SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).

Warchant avatar Oct 14 '23 10:10 Warchant

I just added -L$(ASAN_DIR) and -lasan to link flags, and now asan works. (Windows11, inside WSL2).

Hi @Warchant. Thanks for your feedback. It also worked on my machine when using those flags:

zig cc main.c -L/usr/lib/gcc/x86_64-linux-gnu/11/ -lasan -fsanitize=address -o main

g-berthiaume avatar Nov 28 '23 20:11 g-berthiaume