This shows you the differences between two versions of the page.
|
ep:labs:04:contents:tasks:ex1 [2026/03/23 21:20] radu.mantu |
ep:labs:04:contents:tasks:ex1 [2026/03/24 12:23] (current) radu.mantu |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ==== 01. [10p] Memory Leaks & Dynamic Analysis ==== | + | ==== 01. [10p] Valgrind ==== |
| Dynamic analysis tools can observe a running process and report memory-related | Dynamic analysis tools can observe a running process and report memory-related | ||
| Line 9: | Line 9: | ||
| === [5p] Task A - Writing a leaky program === | === [5p] Task A - Writing a leaky program === | ||
| - | Create the following file as ''leak.c'': | + | Read the contents of ''leak.c'' and compile it: |
| - | <code c> | + | |
| - | #include <stdlib.h> | + | |
| - | #include <string.h> | + | |
| - | + | ||
| - | void leaky_function() { | + | |
| - | char *buf = malloc(256); | + | |
| - | strcpy(buf, "this memory will never be freed"); | + | |
| - | /* buf is never passed to free() */ | + | |
| - | } | + | |
| - | + | ||
| - | int main() { | + | |
| - | for (int i = 0; i < 10; i++) | + | |
| - | leaky_function(); | + | |
| - | return 0; | + | |
| - | } | + | |
| - | </code> | + | |
| - | + | ||
| - | Compile it: | + | |
| <code bash> | <code bash> | ||
| $ gcc -g -o leak leak.c | $ gcc -g -o leak leak.c | ||
| Line 53: | Line 35: | ||
| - At what line number does Valgrind point as the origin of the leak? Why is that line significant rather than the line where the pointer goes out of scope? | - At what line number does Valgrind point as the origin of the leak? Why is that line significant rather than the line where the pointer goes out of scope? | ||
| - Re-compile **without** the ''-g'' flag and run Valgrind again. What information is now missing from the report, and why? | - Re-compile **without** the ''-g'' flag and run Valgrind again. What information is now missing from the report, and why? | ||
| - | |||
| - | HINTS: heap allocation; call stack; debug symbols | ||
| <solution -hidden> | <solution -hidden> | ||
| Line 69: | Line 49: | ||
| </solution> | </solution> | ||
| + | <note tip> | ||
| + | **Troubleshooting** | ||
| + | ----- | ||
| + | On certain distributions such as CachyOS, you may get the following error: | ||
| + | <code> | ||
| + | valgrind: Fatal error at startup: a function redirection | ||
| + | valgrind: which is mandatory for this platform-tool combination | ||
| + | valgrind: cannot be set up. Details of the redirection are: | ||
| + | </code> | ||
| + | **valgrind** need the DWARF debug info for **libc** in order to function properly. If the ELF file itself doesn't have it, **valgrind** will try to use [[https://man.archlinux.org/man/debuginfod-find.1|debuginfod find]] to download it using the **Build ID** stored in the ''.note.gnu.build-id'' section. If the **debuginfod** server doesn't have it either, your only hope of getting it to work is: | ||
| + | * recompiling **glibc** with debug symbols (out of the question) | ||
| + | * starting a docker container with Ubuntu, Debian, Arch Linux, etc. | ||
| + | </note> | ||