X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/deaa7bace2025f1485a265e036b3542f1fbe2701..HEAD:/instrument-functions.c diff --git a/instrument-functions.c b/instrument-functions.c index 5c546125..ba0a56a5 100644 --- a/instrument-functions.c +++ b/instrument-functions.c @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include @@ -33,14 +31,10 @@ * If entering in a function it prints also the calling function name with * file name and line number. * - * To configure the printing of only the global functions names: - * $ make instrument_global - * - * To go back to print all the functions names: - * $ make instrument_all - * - * To print nothing, like with no instrumentation: - * $ make instrument_off + * If the environment variable INSTRUMENT is + * unset or set to an empty string, print nothing, like with no instrumentation + * set to "all" or "a", print all the functions names + * set to "global" or "g", print only the global functions names */ #define ND_NO_INSTRUMENT __attribute__((no_instrument_function)) @@ -73,12 +67,6 @@ __cyg_profile_func_exit(void *this_fn, void *call_site) print_debug(this_fn, call_site, EXIT); } -/* If this file exists, print only the global functions */ -#define ND_FILE_FLAG_GLOBAL "instrument_functions_global.devel" - -/* If this file exists, print nothing, like with no instrumentation */ -#define ND_FILE_FLAG_OFF "instrument_functions_off.devel" - static void print_debug(void *this_fn, void *call_site, action_type action) { static bfd* abfd; @@ -86,28 +74,53 @@ static void print_debug(void *this_fn, void *call_site, action_type action) static long symcount; static asection *text; static bfd_vma vma; - static int print_only_global; - symbol_info syminfo; - struct stat statbuf; - int i, found; + static int instrument_set; + static int instrument_off; + static int instrument_global; + + if (!instrument_set) { + static char *instrument_type; + + /* Get the configuration environment variable INSTRUMENT value if any */ + instrument_type = getenv("INSTRUMENT"); + /* unset or set to an empty string ? */ + if (instrument_type == NULL || + !strncmp(instrument_type, "", sizeof(""))) { + instrument_off = 1; + } else { + /* set to "global" or "g" ? */ + if (!strncmp(instrument_type, "global", sizeof("global")) || + !strncmp(instrument_type, "g", sizeof("g"))) + instrument_global = 1; + else if (strncmp(instrument_type, "all", sizeof("all")) && + strncmp(instrument_type, "a", sizeof("a"))) { + fprintf(stderr, "INSTRUMENT can be only \"\", \"all\", \"a\", " + "\"global\" or \"g\".\n"); + exit(1); + } + } + instrument_set = 1; + } - if (!stat(ND_FILE_FLAG_OFF, &statbuf)) - return; + if (instrument_off) + return; /* If no errors, this block should be executed one time */ if (!abfd) { char pgm_name[1024]; long symsize; - if (!stat(ND_FILE_FLAG_GLOBAL, &statbuf)) - print_only_global = 1; - ssize_t ret = readlink("/proc/self/exe", pgm_name, sizeof(pgm_name)); if (ret == -1) { - perror("failed to find executable\n"); + perror("failed to find executable"); return; } - pgm_name[ret] = 0; + if (ret == sizeof(pgm_name)) { + /* no space for the '\0' */ + printf("truncation may have occurred\n"); + return; + } + pgm_name[ret] = '\0'; bfd_init(); @@ -127,11 +140,11 @@ static void print_debug(void *this_fn, void *call_site, action_type action) return; } - symtab = (asymbol **)malloc(symsize); + symtab = (asymbol **)malloc((size_t)symsize); symcount = bfd_canonicalize_symtab(abfd, symtab); if (symcount < 0) { - free (symtab); - bfd_perror ("bfd_canonicalize_symtab"); + free(symtab); + bfd_perror("bfd_canonicalize_symtab"); return; } @@ -142,7 +155,11 @@ static void print_debug(void *this_fn, void *call_site, action_type action) vma = text->vma; } - if (print_only_global) { + if (instrument_global) { + symbol_info syminfo; + int found; + long i; + i = 0; found = 0; while (i < symcount && !found) { @@ -169,6 +186,8 @@ static void print_debug(void *this_fn, void *call_site, action_type action) &file, &func, &line)) { printf("[ERROR bfd_find_nearest_line this_fn]"); } else { + int i; + if (action == ENTER) profile_func_level += 1; /* Indentation */ @@ -185,7 +204,8 @@ static void print_debug(void *this_fn, void *call_site, action_type action) printf("%s", func); printf(" (%d)", profile_func_level); /* Print the "from" part except for the main function) */ - if (action == ENTER && strncmp(func, "main", sizeof("main"))) { + if (action == ENTER && func != NULL && + strncmp(func, "main", sizeof("main"))) { /* Calling function */ if ((bfd_vma)call_site < vma) { printf("[ERROR address call_site]");