Clang: Difference between revisions
(3 intermediate revisions by the same user not shown) | |||
Line 61: | Line 61: | ||
strip --strip-all some.elf |
strip --strip-all some.elf |
||
sha256sum some.elf |
sha256sum some.elf |
||
</source> |
|||
=== Get list of standard compiler defines === |
|||
<source lang="bash"> |
|||
clang -dM -E -x c /dev/null |
|||
# #define _LP64 1 |
|||
# #define __ATOMIC_ACQUIRE 2 |
|||
# #define __ATOMIC_ACQ_REL 4 |
|||
# #define __ATOMIC_CONSUME 1 |
|||
# #define __ATOMIC_RELAXED 0 |
|||
</source> |
|||
=== Detect optimization levels === |
|||
This can't detect all levels but at least some of them (from [https://stackoverflow.com/questions/31718637/determine-optimization-level-in-preprocessor SO]): |
|||
<source lang="bash"> |
|||
clang -Xpreprocessor -dM -E - < /dev/null > 1 |
|||
clang -Xpreprocessor -dM -O -E - < /dev/null > 2 |
|||
diff 1 2 |
|||
# 53a54 |
|||
# > #define __OPTIMIZE__ 1 |
|||
# 154d155 |
|||
# < #define __NO_INLINE__ 1 |
|||
</source> |
</source> |
||
Line 129: | Line 152: | ||
The simplest for us was to uninstall gcc-9. Another solution is to install g++-9. Also it seems that clang uses some kind of prioritization, so in fact reinstalling gcc-8/g++-8 may work as well. |
The simplest for us was to uninstall gcc-9. Another solution is to install g++-9. Also it seems that clang uses some kind of prioritization, so in fact reinstalling gcc-8/g++-8 may work as well. |
||
=== UBSAN / ASAN troubleshooting === |
|||
;References |
|||
* https://clang.llvm.org/docs/AddressSanitizer.html |
|||
* https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html |
|||
;Build |
|||
* For ASAN: |
|||
:* Use compile and link flags <code>-fsanitize=address</code>. |
|||
:* It is also recommended to use compile flag <code>-fno-omit-frame-pointer</code> for better stack trace. |
|||
<source lang="bash"> |
|||
# Compile |
|||
clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc |
|||
# Link |
|||
clang++ -g -fsanitize=address example_UseAfterFree.o |
|||
</source> |
|||
* For UBSAN: |
|||
:* Use compile and link flags <code>-fsanitize=undefined</code>. |
|||
;Troubleshoot: |
|||
* Error <code>undefined reference to typeinfo</code> when linking [https://stackoverflow.com/questions/37358573/why-does-fsanitize-undefined-cause-undefined-reference-to-typeinfo SO] |
|||
:* Fix is to flag <code>-fno-sanitize=vptr</code>. |
|||
=== No debug symbols === |
|||
Recent version of clang uses DWARF V5. The old debug info can still be used with compile and link flag j<code>-fdebug-default-version=4</code>. |
Latest revision as of 23:00, 11 May 2023
Links
Clang on Windows
LLVM-MinGW
- Get packages from https://github.com/mstorsjo/llvm-mingw
The best port of LLVM/Clang on Windows I tried.
- No dependency on Visual Studio.
- Support 32-bit and 64-bit targets.
- Support sanitizers (ASAN, UBSAN).
MSYS2
MSYS2 now provides clang 9.0 packages.
- No dependency on Visual Studio.
- Support 32-bit and 64-bit targets.
- But does not support sanitizers (ASAN, UBSAN).
Official LLVM
Packages from the official LLVM at http://releases.llvm.org/download.html.
- DEPEND on Visual Studio for linking
- Support 32-bit and 64-bit targets.
- (Maybe) support sanitizers (ASAN, UBSAN).
Tips
Get Stack Pointer
Use this macro [1]:
#define current_stack_pointer ({ \
register unsigned long esp asm("esp"); \
asm("" : "=r"(esp)); \
esp; \
})
Turn errors into warning
-Wno-error=foo Turn warning “foo” into an warning even if -Werror is specified.
Enable all warnings: -Weverything
-Weverything
means enable all current and future warnings. See Better Apps with Clang's Weverything or Wall is a Lie!
Make deterministic / reproducible builds
Things to look at:
__DATE__
and__TIME__
. On clang, we can doexport ZERO_AR_DATE=1
.__FILE__
. On clang, we can add a flag-ffile-prefix-map=/some/local/build/path=.
.__LINE__
.- some randomness introduced by compiler: Use flag
-frandom-seed=0x${checksum}
.
Some script I used:
ag -l __LINE__ | xargs sed -ri 's/__LINE__/1/g'
make NODEBUG=1 some.elf # Optional, but ideally build without flag -g
strip --strip-all some.elf
sha256sum some.elf
Get list of standard compiler defines
clang -dM -E -x c /dev/null
# #define _LP64 1
# #define __ATOMIC_ACQUIRE 2
# #define __ATOMIC_ACQ_REL 4
# #define __ATOMIC_CONSUME 1
# #define __ATOMIC_RELAXED 0
Detect optimization levels
This can't detect all levels but at least some of them (from SO):
clang -Xpreprocessor -dM -E - < /dev/null > 1
clang -Xpreprocessor -dM -O -E - < /dev/null > 2
diff 1 2
# 53a54
# > #define __OPTIMIZE__ 1
# 154d155
# < #define __NO_INLINE__ 1
Troubleshoot
iostream not found
This is a funny one. Simple Hello, World program that fails with an
#include <iostream>
using namespace std;
int main() {
cout << "Hello, World" << endl;
return 0;
}
clang++ main.cpp
# main.cpp:1:10: fatal error: 'iostream' file not found
# #include <iostream>
# ^~~~~~~~~~
# 1 error generated.
Luckily StackOverflow comes to the rescue.
The problem is that we have several gcc/g++ installation, and the one selected by clang doesn't have the c++ headers.
$ clang++ -v main.cpp
clang version 7.0.1-8 (tags/RELEASE_701/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/10
Found candidate GCC installation: /usr/bin/../lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Candidate multilib: .;@m64
Selected multilib: .;@m64
"/usr/lib/llvm-7/bin/clang" -cc1 [...]
clang -cc1 version 7.0.1 based upon LLVM 7.0.1 default target x86_64-pc-linux-gnu
ignoring nonexistent directory "/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/backward"
ignoring nonexistent directory "/include"
ignoring duplicate directory "/usr/include/clang/7.0.1/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++
/usr/include/clang/7.0.1/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
main.cpp:1:10: fatal error: 'iostream' file not found
#include <iostream>
^~~~~~~~~~
1 error generated.
The simplest for us was to uninstall gcc-9. Another solution is to install g++-9. Also it seems that clang uses some kind of prioritization, so in fact reinstalling gcc-8/g++-8 may work as well.
UBSAN / ASAN troubleshooting
- References
- https://clang.llvm.org/docs/AddressSanitizer.html
- https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
- Build
- For ASAN:
- Use compile and link flags
-fsanitize=address
. - It is also recommended to use compile flag
-fno-omit-frame-pointer
for better stack trace.
- Use compile and link flags
# Compile
clang++ -O1 -g -fsanitize=address -fno-omit-frame-pointer -c example_UseAfterFree.cc
# Link
clang++ -g -fsanitize=address example_UseAfterFree.o
- For UBSAN:
- Use compile and link flags
-fsanitize=undefined
.
- Use compile and link flags
- Troubleshoot
- Error
undefined reference to typeinfo
when linking SO
- Fix is to flag
-fno-sanitize=vptr
.
- Fix is to flag
No debug symbols
Recent version of clang uses DWARF V5. The old debug info can still be used with compile and link flag j-fdebug-default-version=4
.