diff options
-rw-r--r-- | md/notes/undefined_c/titles.md | 144 |
1 files changed, 140 insertions, 4 deletions
diff --git a/md/notes/undefined_c/titles.md b/md/notes/undefined_c/titles.md index 3c6daa9..fb8213a 100644 --- a/md/notes/undefined_c/titles.md +++ b/md/notes/undefined_c/titles.md @@ -7,7 +7,7 @@ There is possible to run piece of code inside online c compiler like https://www Or run locally. With base check is done with gcc compiler. There are many small tricks around running C code in practice that aren't covered in any generic tutorials, so here is list of topics that may arise while coding real C code outside of tutorials. For each case there is just small example, each of those could -take whole chapter on its own. +take whole chapter on its own. ## Compile @@ -681,9 +681,18 @@ $ ldd static_elf Statically compiled file should work on most platforms. + +### Atomic +HERE + +### Multithreading +HERE + + <!-- ### stdin,stdout,stderr ### Styles + ---> @@ -1285,16 +1294,143 @@ Gcov file content. So we scant see with line wasnt executed. ### Profiling +Some parts of code can take substantial amount of time and those parts need to be identified. +```c +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +void slow_sin() { + float r=0.0f; + for (int i=0;i<10000000;i++) { + r += sinf(M_PI/8); + } +} -### Canary +void slower_sin() { + double r=0.0f; + for (int i=0;i<10000000;i++) { + r += sin(M_PI/8); + } +} +void fast_sin() { + float pre_calc = sinf(M_PI/8); + float r = 0.0f; + for (int i=0;i<10000000;i++) { + r += pre_calc; + } +} + +int main() { + slow_sin(); + slower_sin(); + fast_sin(); +} +``` + +Compile and rung with profiling + +``` +gcc -pg perf_speed.c -o perf_speed -lm +./perf_speed +gprof perf_speed gmon.cov +``` + +### Sanitizer + +C as a greate language have good features in standart such as undefined behaviour. And +also there is possible to overwrite any data you whant with your code. One of the favorite +mistake is to write some buffer overruns. Its possible to catch this type of errors with +stack protection + +So in code belove there is possible to write in to array of size 8 more then 8 characters. This is because the is no any boundry check. +C runtime will be able to detect this kind of things. + + +```c +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void fun(char *str,int size) { + char local_var[8]; + memcpy(local_var, str, size); + printf("Whats inside a stack? %s\n",local_var); +} + +int main() { + char some_str1[] = "Hello!"; + char some_str2[] = "Hello all!!!"; + + fun(some_str1,strlen(some_str1)); + fun(some_str2,strlen(some_str2)); +} +``` + +``` +Whats inside a stack? Hello! +Whats inside a stack? Hello all!!!<����Fp�� +*** stack smashing detected ***: terminated +fish: Job 1, './stack_overrun' terminated by signal SIGABRT (Abort) +``` + +If this isnt happening there is possible to add __-fstack-protector__ to compile flags. + +C have whole list of undefined behaviours incorporated in standard +https://en.cppreference.com/w/c/language/behavior + + + +functions __f__ variable __a__ isnt initialized so its undefined behaviour but there still will be some value. Run few +times and each time it returns new value when __f(0)__. +```c +#include <stdio.h> + +size_t f(int x) +{ + size_t a; + if(x) // either x nonzero or UB + a = 42; + return a; +} + +int main() { + printf("%d\n",f(0)); + printf("%d\n",f(1)); + printf("%d\n",f(42)); +} +``` + +Division by zero. Function __f__ dont check if divisor is 0. Programm going to abort. +add flag __-fsanitize=integer-divide-by-zero__ and it will be detected at runtime + +```c +#include <stdio.h> + +size_t f(int x) +{ + return 10/x; +} + +int main() { + printf("%d\n",f(0)); + printf("%d\n",f(1)); + printf("%d\n",f(42)); +} +``` + +``` +undefined_b.c:5:14: runtime error: division by zero +fish: Job 1, './undefined_b' terminated by signal SIGFPE (Floating point exception) +``` + + +### FARMA-C -### Atomic -### Multithreading ### Write plugins |