autoconf: Enhance the --enable-instrument-functions result output

It prints now, by default, also the static functions names.

To configure the printing of only the global functions names, as before:
$ make instrument_global

To go back to print all the functions names:
$ make instrument_all

In case of truncation, the indentation level is reset to its previous
level in pretty_print_packet().

[skip ci]
This commit is contained in:
Francois-Xavier Le Bail 2022-01-20 19:26:22 +01:00
parent 26c266dca5
commit 6d854639ea
5 changed files with 91 additions and 22 deletions

View File

@ -389,6 +389,13 @@ all: $(PROG)
$(PROG): $(OBJ) @V_PCAPDEP@ $(LIBNETDISSECT)
@rm -f $@
$(CC) $(FULL_CFLAGS) $(LDFLAGS) -o $@ $(OBJ) $(LIBNETDISSECT) $(LIBS)
nm $(PROG) | grep ' [tT] ' > $(PROG)_instrument_functions.nm
instrument_all: $(PROG)
nm $(PROG) | grep ' [tT] ' > $(PROG)_instrument_functions.nm
instrument_global: $(PROG)
nm $(PROG) | grep ' [T] ' > $(PROG)_instrument_functions.nm
$(LIBNETDISSECT): $(LIBNETDISSECT_OBJ)
@rm -f $@

8
configure vendored
View File

@ -4399,9 +4399,11 @@ $as_echo "yes" >&6; }
$as_echo "#define ENABLE_INSTRUMENT_FUNCTIONS 1" >>confdefs.h
LOCALSRC="$LOCALSRC instrument-functions.c"
CFLAGS="$CFLAGS -finstrument-functions"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
LIBS="$LIBS -ldl"
# Add '-finstrument-functions' instrumentation option to generate
# instrumentation calls for entry and exit to functions.
# Try to avoid Address Space Layout Randomization (ALSR).
CFLAGS="$CFLAGS -finstrument-functions -fno-stack-protector -fno-pic"
LDFLAGS="$LDFLAGS -fno-stack-protector -no-pie"
;;
*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }

View File

@ -157,9 +157,11 @@ yes) AC_MSG_RESULT(yes)
AC_DEFINE(ENABLE_INSTRUMENT_FUNCTIONS, 1,
[define if you want to build the instrument functions code])
LOCALSRC="$LOCALSRC instrument-functions.c"
CFLAGS="$CFLAGS -finstrument-functions"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
LIBS="$LIBS -ldl"
# Add '-finstrument-functions' instrumentation option to generate
# instrumentation calls for entry and exit to functions.
# Try to avoid Address Space Layout Randomization (ALSR).
CFLAGS="$CFLAGS -finstrument-functions -fno-stack-protector -fno-pic"
LDFLAGS="$LDFLAGS -fno-stack-protector -no-pie"
;;
*) AC_MSG_RESULT(no)
;;

View File

@ -36,30 +36,82 @@ int profile_func_level = -1;
* To instument a static function, remove temporarily the static specifier.
*/
void __cyg_profile_func_enter(void *this_fn, void *call_site)
__attribute__((no_instrument_function));
#ifndef ND_NO_INSTRUMENT
#define ND_NO_INSTRUMENT __attribute__((no_instrument_function))
#endif
void __cyg_profile_func_exit(void *this_fn, void *call_site)
__attribute__((no_instrument_function));
void __cyg_profile_func_enter(void *this_fn, void *call_site) ND_NO_INSTRUMENT;
void __cyg_profile_func_exit(void *this_fn, void *call_site) ND_NO_INSTRUMENT;
/*
* The get_function_name() get the function name by calling dladdr()
* Structure table to store the functions data from FILE_NAME.
* FILE_NAME is generated via:
* $ nm $(PROG) | grep ' [tT] '
* or
* $ nm $(PROG) | grep ' [T] '
*/
static const char *get_function_name(void *func)
__attribute__((no_instrument_function));
#define MAX_FUNCTIONS 20000
static struct {
void *addr;
char type;
char name[128];
} functions[MAX_FUNCTIONS] ;
static int functions_count;
static int initialization_done;
/*
* Read the result of nm in functions[]
*/
#define FILE_NAME "tcpdump_instrument_functions.nm"
void read_functions_table(void) ND_NO_INSTRUMENT;
void
read_functions_table(void)
{
FILE *fp;
int i = 0;
if ((fp = fopen(FILE_NAME, "r")) == NULL) {
printf("Warning: Cannot open \"%s\" file\n", FILE_NAME);
return;
}
while (i < MAX_FUNCTIONS && fscanf(fp, "%p %c %s", &functions[i].addr,
&functions[i].type, functions[i].name) != EOF)
i++;
fclose(fp);
functions_count = i;
}
/*
* Get the function name by searching in functions[]
*/
static const char * get_function_name(void *func) ND_NO_INSTRUMENT;
static const char *
get_function_name(void *func)
{
Dl_info info;
const char *function_name;
if (dladdr(func, &info))
function_name = info.dli_sname;
int i = 0;
int found = 0;
if (!initialization_done) {
read_functions_table();
initialization_done = 1;
}
while (i < functions_count) {
if (functions[i].addr == func) {
found = 1;
break;
}
i++;
}
if (found)
return (functions[i].name);
else
function_name = NULL;
return function_name;
return NULL;
}
void

10
print.c
View File

@ -310,6 +310,7 @@ get_if_printer(int type)
#ifdef ENABLE_INSTRUMENT_FUNCTIONS
extern int profile_func_level;
static int pretty_print_packet_level = -1;
#endif
void
@ -322,6 +323,11 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
if (ndo->ndo_print_sampling && packets_captured % ndo->ndo_print_sampling != 0)
return;
#ifdef ENABLE_INSTRUMENT_FUNCTIONS
if (pretty_print_packet_level == -1)
pretty_print_packet_level = profile_func_level;
#endif
if (ndo->ndo_packet_number)
ND_PRINT("%5u ", packets_captured);
@ -411,8 +417,8 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
/* Print the full packet */
ndo->ndo_ll_hdr_len = 0;
#ifdef ENABLE_INSTRUMENT_FUNCTIONS
/* truncation => reassignment, currently: 1 (main is 0) */
profile_func_level = 1;
/* truncation => reassignment */
profile_func_level = pretty_print_packet_level;
#endif
break;
}