prog:gcc
Différences
Ci-dessous, les différences entre deux révisions de la page.
Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
prog:gcc [2020/02/25 00:11] – Ajout de la table virtuelle uniquement root | prog:gcc [2024/11/12 12:48] (Version actuelle) – Déplacement des sanitizer vers une page dédiée root | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
Nightly pour [[https:// | Nightly pour [[https:// | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | ====Ubuntu==== | ||
+ | |||
+ | * Installation en parallèle | ||
+ | |||
+ | Ubuntu ne fournit pas de méthode 100% automatique. Il faut passer manuellement par '' | ||
+ | |||
+ | <code bash> | ||
+ | sudo update-alternatives --install / | ||
+ | </ | ||
+ | |||
+ | Utiliser pour switcher entre les versions : | ||
+ | |||
+ | <code bash> | ||
+ | sudo update-alternatives --config gcc | ||
+ | </ | ||
=====Diagnostic===== | =====Diagnostic===== | ||
Ligne 52: | Ligne 70: | ||
</ | </ | ||
- | * clang : '' | + | * clang : '' |
+ | |||
+ | Ci-dessous, on affiche que le contenu des '' | ||
< | < | ||
- | ; ModuleID = ' | + | *** Dumping AST Record Layout |
- | source_filename = " | + | 0 | class VirtualBase |
- | target datalayout | + | 0 | |
- | target triple | + | | [sizeof=8, dsize=8, align=8, |
+ | | nvsize=8, nvalign=8] | ||
- | %class.VirtualDerived = type <{ %class.VirtualBase, | + | *** Dumping AST Record Layout |
- | %class.VirtualBase = type { i32 (...)** } | + | |
- | + | | |
- | $_ZN14VirtualDerivedC1Ev = comdat any | + | |
- | + | | |
- | $_ZN14VirtualDerivedC2Ev = comdat any | + | | [sizeof=16, dsize=12, align=8, |
- | + | | nvsize=12, nvalign=8] | |
- | $_ZN11VirtualBaseC2Ev = comdat any | + | |
- | + | ||
- | $_ZN14VirtualDerived4tickEi = comdat any | + | |
- | + | ||
- | $_ZTV14VirtualDerived = comdat any | + | |
- | + | ||
- | $_ZTS14VirtualDerived = comdat any | + | |
- | + | ||
- | $_ZTS11VirtualBase = comdat any | + | |
- | + | ||
- | $_ZTI11VirtualBase = comdat any | + | |
- | + | ||
- | $_ZTI14VirtualDerived = comdat any | + | |
- | + | ||
- | $_ZTV11VirtualBase = comdat any | + | |
- | + | ||
- | @_ZTV14VirtualDerived = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8*, i8* }* @_ZTI14VirtualDerived to i8*), i8* bitcast (i32 (%class.VirtualDerived*, | + | |
- | @_ZTVN10__cxxabiv120__si_class_type_infoE = external global i8* | + | |
- | @_ZTS14VirtualDerived = linkonce_odr constant [17 x i8] c" | + | |
- | @_ZTVN10__cxxabiv117__class_type_infoE = external global i8* | + | |
- | @_ZTS11VirtualBase = linkonce_odr constant [14 x i8] c" | + | |
- | @_ZTI11VirtualBase = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv117__class_type_infoE, | + | |
- | @_ZTI14VirtualDerived = linkonce_odr constant { i8*, i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__si_class_type_infoE, | + | |
- | @_ZTV11VirtualBase = linkonce_odr unnamed_addr constant { [3 x i8*] } { [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI11VirtualBase to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*)] }, comdat, align 8 | + | |
- | + | ||
- | ; Function Attrs: noinline nounwind optnone | + | |
- | define void @_Z1fv() #0 { | + | |
- | entry: | + | |
- | %v = alloca %class.VirtualDerived, align 8 | + | |
- | call void @_ZN14VirtualDerivedC1Ev(%class.VirtualDerived* %v) | + | |
- | ret void | + | |
- | } | + | |
- | + | ||
- | ; Function Attrs: noinline nounwind optnone | + | |
- | define linkonce_odr void @_ZN14VirtualDerivedC1Ev(%class.VirtualDerived* %this) unnamed_addr #0 comdat align 2 { | + | |
- | entry: | + | |
- | %this.addr = alloca %class.VirtualDerived*, | + | |
- | store %class.VirtualDerived* %this, %class.VirtualDerived** %this.addr, align 8 | + | |
- | %this1 = load %class.VirtualDerived*, | + | |
- | call void @_ZN14VirtualDerivedC2Ev(%class.VirtualDerived* %this1) | + | |
- | ret void | + | |
- | } | + | |
- | + | ||
- | ; Function Attrs: noinline nounwind optnone | + | |
- | define linkonce_odr void @_ZN14VirtualDerivedC2Ev(%class.VirtualDerived* %this) unnamed_addr #0 comdat align 2 { | + | |
- | entry: | + | |
- | %this.addr = alloca %class.VirtualDerived*, | + | |
- | store %class.VirtualDerived* %this, %class.VirtualDerived** %this.addr, align 8 | + | |
- | %this1 = load %class.VirtualDerived*, | + | |
- | %0 = bitcast %class.VirtualDerived* %this1 to %class.VirtualBase* | + | |
- | call void @_ZN11VirtualBaseC2Ev(%class.VirtualBase* %0) #1 | + | |
- | %1 = bitcast %class.VirtualDerived* %this1 to i32 (...)*** | + | |
- | store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV14VirtualDerived, | + | |
- | %m_counter | + | |
- | store i32 0, i32* %m_counter, align 8 | + | |
- | ret void | + | |
- | } | + | |
- | + | ||
- | ; Function Attrs: noinline nounwind optnone | + | |
- | define linkonce_odr void @_ZN11VirtualBaseC2Ev(%class.VirtualBase* %this) unnamed_addr #0 comdat align 2 { | + | |
- | entry: | + | |
- | %this.addr = alloca %class.VirtualBase*, | + | |
- | store %class.VirtualBase* %this, %class.VirtualBase** %this.addr, align 8 | + | |
- | %this1 = load %class.VirtualBase*, | + | |
- | %0 = bitcast %class.VirtualBase* %this1 to i32 (...)*** | + | |
- | store i32 (...)** bitcast (i8** getelementptr inbounds ({ [3 x i8*] }, { [3 x i8*] }* @_ZTV11VirtualBase, | + | |
- | ret void | + | |
- | } | + | |
- | + | ||
- | ; Function Attrs: noinline nounwind optnone | + | |
- | define linkonce_odr i32 @_ZN14VirtualDerived4tickEi(%class.VirtualDerived* %this, i32 %n) unnamed_addr #0 comdat align 2 { | + | |
- | entry: | + | |
- | %this.addr | + | |
- | %n.addr | + | |
- | store %class.VirtualDerived* %this, %class.VirtualDerived** %this.addr, align 8 | + | |
- | store i32 %n, i32* %n.addr, align 4 | + | |
- | %this1 | + | |
- | %0 = load i32, i32* %n.addr, align 4 | + | |
- | | + | |
- | %1 = load i32, i32* %m_counter, align 8 | + | |
- | %add = add nsw i32 %1, %0 | + | |
- | store i32 %add, i32* %m_counter, align 8 | + | |
- | %m_counter2 = getelementptr inbounds %class.VirtualDerived, | + | |
- | %2 = load i32, i32* %m_counter2, | + | |
- | ret i32 %2 | + | |
- | } | + | |
- | + | ||
- | declare void @__cxa_pure_virtual() unnamed_addr | + | |
- | + | ||
- | attributes #0 = { noinline nounwind optnone " | + | |
- | attributes #1 = { nounwind } | + | |
- | + | ||
- | !llvm.module.flags = !{!0} | + | |
- | !llvm.ident = !{!1} | + | |
- | + | ||
- | !0 = !{i32 1, !" | + | |
- | !1 = !{!" | + | |
</ | </ | ||
Ligne 192: | Ligne 116: | ||
[[https:// | [[https:// | ||
- | =====Commun avec clang===== | ||
- | ====Sanitizer==== | ||
- | Il existe '' | ||
- | ===address=== | ||
- | Il détecte des erreurs de type global-buffer-overflow, | ||
- | [[https:// | ||
- | * global-buffer-overflow | + | ====Couverture de code==== |
- | <file c main.c> | + | |
- | int global_array[100] | + | |
- | int main(int argc, char **argv) { | + | Options à ajouter à la compilation : '' |
- | return global_array[argc+100]; | + | |
- | } | + | |
- | </ | + | |
- | gcc main.c | + | Options à ajouter au lieur : '' |
- | ================================================================= | + | Puis exécuter le ou les programmes. Attention, pas d' |
- | ==2500==ERROR: | + | |
- | READ of size 4 at 0x000000740cf4 thread T0 | + | |
- | #0 0x50d9be in main /tmp/main.c:4:10 | + | |
- | #1 0x7f1208faa461 in __libc_start_main / | + | |
- | #2 0x419709 in _start (/ | + | |
- | + | ||
- | 0x000000740cf4 is located 4 bytes to the right of global variable | + | |
- | SUMMARY: AddressSanitizer: | + | |
- | Shadow bytes around the buggy address: | + | |
- | 0x0000800e0140: | + | |
- | 0x0000800e0150: | + | |
- | 0x0000800e0160: | + | |
- | 0x0000800e0170: | + | |
- | 0x0000800e0180: | + | |
- | => | + | |
- | 0x0000800e01a0: | + | |
- | 0x0000800e01b0: | + | |
- | 0x0000800e01c0: | + | |
- | 0x0000800e01d0: | + | |
- | 0x0000800e01e0: | + | |
- | Shadow byte legend (one shadow byte represents 8 application bytes): | + | |
- | Addressable: | + | |
- | Partially addressable: | + | |
- | Heap left redzone: | + | |
- | Freed heap region: | + | |
- | Stack left redzone: | + | |
- | Stack mid redzone: | + | |
- | Stack right redzone: | + | |
- | Stack after return: | + | |
- | Stack use after scope: | + | |
- | Global redzone: | + | |
- | Global init order: | + | |
- | Poisoned by user: f7 | + | |
- | Container overflow: | + | |
- | Array cookie: | + | |
- | Intra object redzone: | + | |
- | ASan internal: | + | |
- | Left alloca redzone: | + | |
- | Right alloca redzone: | + | |
- | ==2500==ABORTING | + | |
- | [[prog: | + | <code bash> |
- | + | lcov --capture | |
- | * heap-use-after-free | + | lcov --remove build/coverage.info "/usr/include/*" |
- | <file c main2.cc> | + | genhtml |
- | int main(int argc, char **argv) { | + | find build/coverage |
- | int *array = new int[100]; | + | </code> |
- | delete [] array; | + | |
- | return array[argc]; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | g++ main2.c | + | |
- | + | ||
- | ================================================================= | + | |
- | ==2765==ERROR: | + | |
- | READ of size 4 at 0x614000000044 thread T0 | + | |
- | #0 0x512444 in main / | + | |
- | #1 0x7fd8d0086461 in __libc_start_main / | + | |
- | #2 0x419d29 in _start (/ | + | |
- | + | ||
- | 0x614000000044 is located 4 bytes inside of 400-byte region [0x614000000040, | + | |
- | freed by thread T0 here: | + | |
- | #0 0x50ef30 in operator delete[](void*) / | + | |
- | #1 0x5123f6 in main / | + | |
- | #2 0x7fd8d0086461 in __libc_start_main / | + | |
- | #3 0x419d29 in _start (/ | + | |
- | + | ||
- | previously allocated by thread T0 here: | + | |
- | #0 0x50e1c8 in operator new[](unsigned long) / | + | |
- | #1 0x5123d4 in main / | + | |
- | #2 0x7fd8d0086461 in __libc_start_main / | + | |
- | #3 0x419d29 in _start (/ | + | |
- | + | ||
- | SUMMARY: AddressSanitizer: | + | |
- | Shadow bytes around the buggy address: | + | |
- | 0x0c287fff7fb0: | + | |
- | 0x0c287fff7fc0: | + | |
- | 0x0c287fff7fd0: | + | |
- | 0x0c287fff7fe0: | + | |
- | 0x0c287fff7ff0: | + | |
- | => | + | |
- | 0x0c287fff8010: | + | |
- | 0x0c287fff8020: | + | |
- | 0x0c287fff8030: | + | |
- | 0x0c287fff8040: | + | |
- | 0x0c287fff8050: | + | |
- | + | ||
- | [[prog: | + | |
- | + | ||
- | ==2787== Command: ./main2 | + | |
- | ==2787== | + | |
- | ==2787== Invalid read of size 4 | + | |
- | ==2787== | + | |
- | ==2787== | + | |
- | ==2787== | + | |
- | ==2787== | + | |
- | ==2787== | + | |
- | ==2787== | + | |
- | ==2787== | + | |
- | + | ||
- | | + | |
- | <file c main3.c> | + | |
- | int *g; | + | |
- | + | ||
- | void LeakLocal() { | + | |
- | int local; | + | |
- | g = & | + | |
- | } | + | |
- | + | ||
- | int main(){ | + | |
- | LeakLocal(); | + | |
- | return *g; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | gcc main3.c -g -o main3 -fsanitize=address | + | |
- | ASAN_OPTIONS=detect_stack_use_after_return=1 ./main3 | + | |
- | + | ||
- | L' | + | |
- | + | ||
- | ================================================================= | + | |
- | ==2907==ERROR: | + | |
- | READ of size 4 at 0x7f57b2a00020 thread T0 | + | |
- | #0 0x50db24 in main / | + | |
- | #1 0x7f57b604d461 in __libc_start_main / | + | |
- | #2 0x419709 in _start (/ | + | |
- | + | ||
- | Address 0x7f57b2a00020 is located in stack of thread T0 at offset 32 in frame | + | |
- | #0 0x50d95f in LeakLocal / | + | |
- | + | ||
- | This frame has 1 object(s): | + | |
- | [32, 36) ' | + | |
- | HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext | + | |
- | (longjmp and C++ exceptions *are* supported) | + | |
- | SUMMARY: AddressSanitizer: | + | |
- | Shadow bytes around the buggy address: | + | |
- | 0x0feb76537fb0: | + | |
- | 0x0feb76537fc0: | + | |
- | 0x0feb76537fd0: | + | |
- | 0x0feb76537fe0: | + | |
- | 0x0feb76537ff0: | + | |
- | => | + | |
- | 0x0feb76538010: | + | |
- | 0x0feb76538020: | + | |
- | 0x0feb76538030: | + | |
- | 0x0feb76538040: | + | |
- | 0x0feb76538050: | + | |
- | + | ||
- | [[prog: | + | |
- | + | ||
- | valgrind | + | |
- | + | ||
- | ==2961== Syscall param exit_group(status) contains uninitialised byte(s) | + | |
- | ==2961== | + | |
- | ==2961== | + | |
- | ==2961== | + | |
- | ==2961== | + | |
- | ==2961== | + | |
- | ==2961== | + | |
- | + | ||
- | ===thread=== | + | |
- | <file cpp main4.cc> | + | |
- | #include < | + | |
- | + | ||
- | int main() { | + | |
- | int x; | + | |
- | std::thread t([& | + | |
- | x = 43; | + | |
- | t.join(); | + | |
- | + | ||
- | return 0; | + | |
- | } | + | |
- | </ | + | |
- | + | ||
- | g++ -std=c++11 main4.c | + | |
- | + | ||
- | <note important> | + | |
- | </note> | + | |
- | + | ||
- | ================== | + | |
- | WARNING: ThreadSanitizer: | + | |
- | Write of size 4 at 0x7ffd04d5b144 by thread T1: | + | |
- | #0 operator() /tmp/main4.c:5 (main4+0x000000400d0b) | + | |
- | #1 __invoke_impl< | + | |
- | | + | |
- | #3 _M_invoke< | + | |
- | #4 operator() / | + | |
- | #5 _M_run / | + | |
- | | + | |
- | + | ||
- | Previous write of size 4 at 0x7ffd04d5b144 by main thread: | + | |
- | #0 main /tmp/ | + | |
- | + | ||
- | Location is stack of main thread. | + | |
- | + | ||
- | Thread T1 (tid=3228, running) created by main thread at: | + | |
- | | + | |
- | #1 std:: | + | |
- | #2 main / | + | |
- | + | ||
- | SUMMARY: ThreadSanitizer: | + | |
- | ================== | + | |
- | ThreadSanitizer: | + | |
- | + | ||
- | [[prog: | + | |
- | + | ||
- | ===undefined=== | + | |
- | <file c main5.c> | + | |
- | int main(int argc, char **argv) | + | |
- | int t = argc << 16; | + | |
- | return t*t; | + | |
- | } | + | |
- | </file> | + | |
- | + | ||
- | gcc -fsanitize=undefined main5.c -g -o main5 | + | |
- | main6.c:3:11: runtime error: signed integer overflow: 65536 * 65536 cannot be represented in type ' | + | Attention, la version de gcov doit correspondre à celle de gcc. |
- | [[prog: | + | En option, on supprime la date pour qu'un diff simple puisse se faire. |
prog/gcc.1582585906.txt.gz · Dernière modification : 2020/02/25 00:11 de root