6

I have several versions of a project checkout out and compiled. If I spot an error, I compare the versions to narrow the problem down. Sometimes I enable sanitizers like the AddressSanitizer. If I re-use an executable, I don't remember whether it was compiled with the sanitizers or not. If the executable works fine, I am not sure whether the bug is not there or whether I did not include the sanitizer in this build. So I have to reconfigure and rebuild to make sure I have the sanitizer included.

Is there a way to check whether an executable has been compiled with a sanitizer?

usr1234567
  • 21,601
  • 16
  • 108
  • 128
  • You can use `ldd` on executable to check if it is linked with libasan.so. Or you can do `objdump -p` see if libasan.so is needed in dymanic sections: `NEEDED libasan.so.0` – Jurasic Feb 04 '16 at 08:59

3 Answers3

15

Address sanitizer can also be compiled statically with the -static-libasan option in GCC. Statically compiling address sanitizer is the default mode in Clang.

If you compile address sanitizer statically then it is obviously not possible to use ldd to verify if your binary is sanitized or not. In this case I use nm and check if there are sanitizer symbols in the binary:

nm -an <executable> | grep asan

Perennialista
  • 1,083
  • 2
  • 12
  • 22
3

You need to use __has_feature(address_sanitizer), see http://clang.llvm.org/docs/AddressSanitizer.html (same for other sanitizers).

Glider
  • 353
  • 3
  • 5
  • That would work. But I am more interested in some command line tool to extract that information. – usr1234567 Feb 03 '16 at 12:32
  • 2
    `nm binary-name | grep '__asan\|__tsan\|__msan'` – Glider Mar 04 '16 at 11:49
  • 2
    What about for GCC? You can use: `#if defined(__SANITIZE_ADDRESS__)` as seen here: https://stackoverflow.com/questions/34813412/how-to-detect-if-building-with-address-sanitizer-when-building-with-gcc-4-8 – thejinx0r Apr 22 '19 at 19:48
  • It is an idea, adding a command line option to tell you whether it is compiled with sanitize or not... – Alexis Wilke Aug 29 '21 at 02:51
  • And in case anyone else comes looking, for undefined behavior sanitizer it's ubsan, not usan. – JoeManiaci Jul 11 '22 at 19:54
1

From man ldd:

ldd prints the shared libraries required by each program or shared library specified on the command line.

As long as address sanitizer requires to link with libasan.so library (actual implementation of sanitizer) you can assume:

  • If ldd won't print shared lib libasan.so it definitely means that address sanitizer is turned off.

  • If ldd will print shared lib libasan.so it means that your linker flags includes -lasan, otherwise you`ll get unresolved symbol error during linking. Highly likely that address sanitizer is enabled, unless you have a bug in building system.

  • Third option if you have bug in your building system. ldd will print libasan.so but address sanitizer will be turned off if you passed to linker -lasan , but didn't pass -fsanitize=address. It means that you linked your executable with address sanitizer but didn't include checks into your executable.

    Or you can do objdump -p to see if libasan.so is needed in dymanic sections: NEEDED libasan.so.0. objdump could give the same(and more) information as ldd.

Jurasic
  • 1,845
  • 1
  • 23
  • 29
  • It sounds like your first bullet point is wrong. If linked statically, `ldd` won't tell you anything and yet it was compiled with `libasan.a`. Finding a reference as @Perennialista mentioned is a more bullet proof idea. – Alexis Wilke Aug 29 '21 at 02:50