Last active
March 4, 2025 10:13
-
-
Save Toliak/b4d5422dd7d436ded4ae321ce1e73814 to your computer and use it in GitHub Desktop.
Revisions
-
Toliak revised this gist
Mar 4, 2025 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,8 @@ # Description Patch for Valgrind commit `2d09ef48e2`. Also works on tag `VALGRIND_3_24_0` Provides logs for callgrind in the format: - Function entering ``` -
Toliak revised this gist
Mar 4, 2025 . 1 changed file with 2 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -153,4 +153,5 @@ The log output (cut): - 6 000000000010924e [app] f2 (/my-project-directory/main.c:34) - 5 0000000000109234 [app] f1 (/my-project-directory/main.c:93) + 6 00000000048d0e00 [libc.so.6] printf (/usr/src/debug/glibc/glibc/stdio-common/printf.c:28) ``` -
Toliak revised this gist
Mar 2, 2025 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -8,7 +8,7 @@ Provides logs for callgrind in the format: ``` - Function exiting ``` - <Stack position (before exit)> [<Module name>] <Function name> (<source line the function will return to, if debug symbols provided>) ``` Also provides two arguments: `--ct-verbose-suppress-module` and `--ct-verbose-suppress-function`. @@ -21,6 +21,7 @@ Consider C code: <details> <summary>main.c</summary> ```c #include <stdio.h> #include <stdlib.h> @@ -117,6 +118,7 @@ int main(int argc, char** argv) { printf("Result: %d\n", f1(a)); } ``` </details> Command to build the code above: -
Toliak revised this gist
Mar 2, 2025 . 1 changed file with 5 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -17,9 +17,11 @@ Multiple module or function names should be separated by a colon. # Example Consider C code: <details> <summary>main.c</summary> ```c #include <stdio.h> #include <stdlib.h> #include <fcntl.h> @@ -115,6 +117,7 @@ int main(int argc, char** argv) { printf("Result: %d\n", f1(a)); } ``` </details> Command to build the code above: ``` -
Toliak revised this gist
Mar 2, 2025 . 1 changed file with 151 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,151 @@ # Description Patch for Valgrind commit `2d09ef48e2`. Provides logs for callgrind in the format: - Function entering ``` + <Stack position> [<Module name>] <Function name> (<source line of the beginning of the called function, if debug symbols provided>) ``` - Function exiting ``` - <Stack position (before exit)> [<Module name>] <Function name> (<source line the exit will return to, if debug symbols provided>) ``` Also provides two arguments: `--ct-verbose-suppress-module` and `--ct-verbose-suppress-function`. The can be used to specify modules and functions for supress, respectively. Multiple module or function names should be separated by a colon. # Example Consider C++ code: ``` #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> // Function declarations int f1(int v); int f2(int v); int f3(int v); int f4(int v); int f5(int v); int f6(int v); int f7(int v); int f8(int v); int f9(int v); int f10(int v); void file_check(void) { int fd = open("/dev/null", O_RDONLY); if (fd == -1) { perror("open"); exit(1); } char buffer[1024]; read(fd, buffer, sizeof(buffer)); close(fd); } // Function definitions int f1(int v) { return f2(v + 1); } int f2(int v) { file_check(); if (v > 10) { return (v - 5); } return f3(v * 2); } int f3(int v) { return f8(v + 3); } int f4(int v) { if (v < 0) { return (v + 10); } return f6(v - 2); } int f5(int v) { return f9(v / 2); } int f6(int v) { if (v % 2 == 0) { return (v + 1); } return f4(v - 1); } int f7(int v) { return f10(v * 3); } int f8(int v) { if (v > 20) { return (v - 10); } return f6(v + 5); } int f9(int v) { return f3(v - 4); } int f10(int v) { if (v == 0) { return 0; // Base case to stop recursion } return f2(v - 1); } int main(int argc, char** argv) { int a = 3; printf("Result: %d\n", f1(a)); } ``` Command to build the code above: ``` gcc main.c -O0 -g -o build/app ``` Command to run callgrind: ``` $MY_VALGRIND_DIR/dist/bin/valgrind --tool=callgrind --ct-verbose=1 --ct-verbose-suppress-module="ld-linux-x86-64.so.2" --ct-verbose-suppress-function="__syscall_cancel:__internal_syscall_cancel" --log-file=./log.txt ./build/app ``` The log output (cut): ``` + 4 000000000010938e [app] main (/my-project-directory/main.c:91) + 5 0000000000109234 [app] f1 (/my-project-directory/main.c:33) + 6 000000000010924e [app] f2 (/my-project-directory/main.c:37) + 7 0000000000109199 [app] file_check (/my-project-directory/main.c:19) + 9 00000000049832d0 [libc.so.6] open (/usr/src/debug/glibc/glibc/io/../sysdeps/unix/sysv/linux/open64.c:30) - 9 00000000049832d0 [libc.so.6] open (/my-project-directory/main.c:20) + 9 0000000004983a20 [libc.so.6] read (/usr/src/debug/glibc/glibc/io/../sysdeps/unix/sysv/linux/read.c:25) - 9 0000000004983a20 [libc.so.6] read (/my-project-directory/main.c:27) + 9 000000000497ee60 [libc.so.6] close (/usr/src/debug/glibc/glibc/io/../sysdeps/unix/sysv/linux/close.c:26) - 9 000000000497ee60 [libc.so.6] close (/my-project-directory/main.c:29) - 7 0000000000109199 [app] file_check (/my-project-directory/main.c:38) + 7 000000000010927a [app] f3 (/my-project-directory/main.c:46) + 8 0000000000109325 [app] f8 (/my-project-directory/main.c:73) + 9 00000000001092dc [app] f6 (/my-project-directory/main.c:62) - 9 00000000001092dc [app] f6 (/my-project-directory/main.c:77) - 8 0000000000109325 [app] f8 (/my-project-directory/main.c:47) - 7 000000000010927a [app] f3 (/my-project-directory/main.c:43) - 6 000000000010924e [app] f2 (/my-project-directory/main.c:34) - 5 0000000000109234 [app] f1 (/my-project-directory/main.c:93) + 6 00000000048d0e00 [libc.so.6] printf (/usr/src/debug/glibc/glibc/stdio-common/printf.c:28) ``` -
Toliak created this gist
Mar 2, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,277 @@ diff --git a/callgrind/callstack.c b/callgrind/callstack.c index fc1d6eeab..acc7c5542 100644 --- a/callgrind/callstack.c +++ b/callgrind/callstack.c @@ -174,6 +174,135 @@ static void function_left(fn_node* fn) } +/* Returns uhhhh the same pointer to the fn_buf. If no fn_buf (or it is "???") -- `fallback_fn_name` + See debug.c, `CLG_(print_addr)` for the reference +*/ +static HChar* CLG_(get_fn_buf_name)(HChar* fn_buf) { + const HChar* fallback_fn_name = "???"; + if (!fn_buf || VG_(strcmp)(fn_buf,"???") == 0) { + return fallback_fn_name; + } + return fn_buf; +} + + +/* Returns shifted pointer to the same allocated string. If no module name -- `fallback_obj_name` + See debug.c, `CLG_(print_addr)` for the reference +*/ +static HChar* CLG_(get_di_obj_name)(DebugInfo *di) { + const HChar* fallback_obj_name = "???"; + UInt i=0, opos=0; + + if (UNLIKELY(!di)) { + return fallback_obj_name; + } + + const HChar* obj_name = VG_(DebugInfo_get_filename)(di); + if (obj_name) { + while(obj_name[i]) { + if (obj_name[i]=='/') { + opos = i+1; + } + i++; + } + + obj_name += opos; + return (obj_name[0]) ? obj_name : fallback_obj_name; + } + + return fallback_obj_name; +} + + +/* Prints source mapped code line + See debug.c, `CLG_(print_addr)` for the reference +*/ +static void CLG_(print_fl_buf_source_line)(UInt di_ln, const HChar* dir_buf, const HChar* fl_buf) { + if (di_ln>0) { + if (dir_buf[0]) { + VG_(printf)("(%s/%s:%u)", dir_buf, fl_buf, di_ln);} + else { + VG_(printf)("(%s:%u)", fl_buf, di_ln); + } + } else { + VG_(printf)("(???)"); + } +} + + +static void CLG_(print_verbose_1_patch)(jCC* jcc, Bool with_jmpaddr) { + const HChar *fn_buf, *fl_buf, *dir_buf; + const HChar *fn_name, *obj_name; + DebugInfo* di; + UInt di_ln; + Addr addr, jmpaddr; + Bool is_blacklisted = False; + + if (jcc && jcc->to && jcc->to->bb) { + // Do not print or even process if there is no jcc + + addr = bb_addr(jcc->to->bb); + jmpaddr = bb_jmpaddr(jcc->from->bb); // TODO: may be bb_addr(jcc->from-bb) useful? + + if (addr != 0) { + CLG_(get_debug_info)(addr, &dir_buf, &fl_buf, &fn_buf, &di_ln, &di); + + fn_name = CLG_(get_fn_buf_name)(fn_buf); + obj_name = CLG_(get_di_obj_name)(di); + + for (SizeT i = 0; i < VG_(sizeXA)(CLG_(clo).suppress_module) && !is_blacklisted; i++) { + const HChar *module = *(HChar**)VG_(indexXA)(CLG_(clo).suppress_module, i); + if (VG_(strncmp)(module, obj_name, 1024) == 0) { + // VG_(printf)("[B] %s blacklisted by %s\n", obj_name, module); + is_blacklisted = True; + break; + } + } + for (SizeT i = 0; i < VG_(sizeXA)(CLG_(clo).suppress_function) && !is_blacklisted; i++) { + const HChar *function = *(HChar**)VG_(indexXA)(CLG_(clo).suppress_function, i); + if (VG_(strncmp)(function, fn_name, 1024) == 0) { + // VG_(printf)("[B] %s blacklisted by %s\n", obj_name, function); + is_blacklisted = True; + break; + } + } + } + + if (!is_blacklisted) { + if (with_jmpaddr) { + VG_(printf)("- %2d ", CLG_(current_call_stack).sp + 1); + } + else { + VG_(printf)("+ %2d ", CLG_(current_call_stack).sp); + } + + VG_(printf)("%016llx ", addr); + + if (addr != 0) { + VG_(printf)("[%s] %s ", obj_name, fn_name); + + if (with_jmpaddr) { + if (jmpaddr != 0) { + CLG_(get_debug_info)(jmpaddr, &dir_buf, &fl_buf, &fn_buf, &di_ln, &di); + CLG_(print_fl_buf_source_line)(di_ln, dir_buf, fl_buf); + } else { + VG_(printf)("(???)"); + } + } + else { + CLG_(print_fl_buf_source_line)(di_ln, dir_buf, fl_buf); + } + } + else { + VG_(printf)("NO_DI"); + } + + VG_(printf)("\n"); + } + } +} + + /* Push call on call stack. * * Increment the usage count for the function called. @@ -270,24 +399,7 @@ void CLG_(push_call_stack)(BBCC* from, UInt jmp, BBCC* to, Addr sp, Bool skip) #if CLG_ENABLE_DEBUG CLG_DEBUGIF(0) { if (CLG_(clo).verbose<2) { - if (jcc && jcc->to && jcc->to->bb) { - const HChar spaces[][41] = { - " . . . . . . . . . .", - " . . . . . . . . . . ", - " . . . . . . . . . . ", - ". . . . . . . . . . " }; - - int s = CLG_(current_call_stack).sp; - UInt* pars = (UInt*) sp; - - BB* bb = jcc->to->bb; - if (s>40) s=40; - VG_(printf)("%s> %s(0x%x, 0x%x, ...) [%s / %#lx]\n", spaces[s%4]+40-s, bb->fn->name, - pars ? pars[1]:0, - pars ? pars[2]:0, - bb->obj->name + bb->obj->last_slash_pos, - (UWord)bb->offset); - } + CLG_(print_verbose_1_patch)(jcc, False); } else if (CLG_(clo).verbose<4) { VG_(printf)("+ %2d ", CLG_(current_call_stack).sp); @@ -368,8 +480,11 @@ void CLG_(pop_call_stack)(void) CLG_(current_call_stack).sp--; #if CLG_ENABLE_DEBUG - CLG_DEBUGIF(1) { - if (CLG_(clo).verbose<4) { + CLG_DEBUGIF(0) { + if (CLG_(clo).verbose<2) { + CLG_(print_verbose_1_patch)(jcc, True); + } + else if (CLG_(clo).verbose<4) { if (jcc) { /* popped JCC target first */ VG_(printf)("- %2d %#lx => ", diff --git a/callgrind/clo.c b/callgrind/clo.c index ce15fc832..7781bf2fd 100644 --- a/callgrind/clo.c +++ b/callgrind/clo.c @@ -399,6 +399,38 @@ void CLG_(update_fn_config)(fn_node* fn) update_fn_config2(fn, fn->name, fn_configs); } +/* String split into XArray */ +static void CLG_(string_split_to_xarray)(const HChar *orig_str, HChar delim, XArray *out_array) { + SizeT j = 0; + SizeT i = 0; + for (i = 0; i < 16 * 1024 * 1024 && orig_str[i] != '\0'; ++i) { + HChar c = orig_str[i]; + if (c == delim) { + if (i > j) { + HChar* new_str = VG_(malloc)("ct_verbose_suppress_module", i - j + 1); + VG_(strncpy)(new_str, orig_str + j, i - j); + new_str[i-j] = 0; + VG_(addToXA)(out_array, (void*)&new_str); + } + // Do not capture empty string + + j = i+1; + } + } + if (i > j) { + HChar* new_str = VG_(malloc)("ct_verbose_suppress_module", i - j + 1); + VG_(strncpy)(new_str, orig_str + j, i - j); + new_str[i-j] = 0; + VG_(printf)("before addToXA2: (%d) %s\n", i-j, new_str); + + VG_(addToXA)(out_array, (void*)&new_str); + } + + // for (SizeT i = 0; i < VG_(sizeXA)(out_array); i++) { + // VG_(printf)("Suppressed modules: %s\n", VG_(indexXA)(out_array, i)); + // } +} + /*--------------------------------------------------------------------*/ /*--- Command line processing ---*/ @@ -466,6 +498,21 @@ Bool CLG_(process_cmd_line_option)(const HChar* arg) else if VG_INT_CLO(arg, "--ct-verbose", CLG_(clo).verbose) {} else if VG_INT_CLO(arg, "--ct-vstart", CLG_(clo).verbose_start) {} + else if VG_STR_CLO(arg, "--ct-verbose-suppress-module", tmp_str) { + CLG_(string_split_to_xarray)(tmp_str, ':', CLG_(clo).suppress_module); + + for (SizeT i = 0; i < VG_(sizeXA)(CLG_(clo).suppress_module); i++) { + VG_(printf)("Suppressed modules: %s\n", *(HChar**)VG_(indexXA)(CLG_(clo).suppress_module, i)); + } + } + else if VG_STR_CLO(arg, "--ct-verbose-suppress-function", tmp_str) { + CLG_(string_split_to_xarray)(tmp_str, ':', CLG_(clo).suppress_function); + + for (SizeT i = 0; i < VG_(sizeXA)(CLG_(clo).suppress_function); i++) { + VG_(printf)("Suppressed functions: %s\n", *(HChar**)VG_(indexXA)(CLG_(clo).suppress_function, i)); + } + } + else if VG_STREQN(12, arg, "--ct-verbose") { fn_config* fnc; HChar* s; @@ -634,6 +681,8 @@ void CLG_(print_debug_usage)(void) " --ct-verbose=<level> Verbosity of standard debug output [0]\n" " --ct-vstart=<BB number> Only be verbose after basic block [0]\n" " --ct-verbose<level>=<func> Verbosity while in <func>\n" +" --ct-verbose-suppress-module=<modules> Suppress output for modules (separated by colon string)\n" +" --ct-verbose-suppress-function=<functions> Suppress output for functions (separated by colon string)\n" #else " (none)\n" #endif @@ -685,5 +734,9 @@ void CLG_(set_clo_defaults)(void) #if CLG_ENABLE_DEBUG CLG_(clo).verbose = 0; CLG_(clo).verbose_start = 0; + CLG_(clo).suppress_function = VG_(newXA)(VG_(malloc), "CLG(set_clo_defaults).sf", + VG_(free), sizeof(HChar *)); + CLG_(clo).suppress_module= VG_(newXA)(VG_(malloc), "CLG(set_clo_defaults).sm", + VG_(free), sizeof(HChar *)); #endif } diff --git a/callgrind/global.h b/callgrind/global.h index 4a988a481..4207e865c 100644 --- a/callgrind/global.h +++ b/callgrind/global.h @@ -123,6 +123,8 @@ struct _CommandLineOptions { #if CLG_ENABLE_DEBUG Int verbose; ULong verbose_start; + XArray *suppress_module; // array of string + XArray *suppress_function; // array of string #endif };