summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2022-01-10 16:37:07 +0100
committerFrancois-Xavier Le Bail <devel.fx.lebail@orange.fr>2022-01-17 20:48:57 +0100
commitc6b7d41176a54da953afdd0047f59a8275cd1374 (patch)
treed62b3668c56f7ec83dccd7cf55fdf4d069357ea0
parent63b104dc5b765f14404449d52a4d307fa17089fa (diff)
downloadtcpdump-c6b7d41176a54da953afdd0047f59a8275cd1374.tar.gz
autoconf: Add the option to print functions names (entry and exit)
This should help some debugging processes. Usage: ./configure --enable-instrument-functions Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, these profiling functions are called and print the function names with indentation and call level. To instument a static function, remove temporarily the static specifier. In case of truncation, the indentation level is reset currently to 1 in pretty_print_packet(), main is level 0.
-rw-r--r--Makefile.in1
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure28
-rw-r--r--configure.ac19
-rw-r--r--instrument-functions.c95
-rw-r--r--print.c8
6 files changed, 154 insertions, 0 deletions
diff --git a/Makefile.in b/Makefile.in
index 2515e661..ca30bb3e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -356,6 +356,7 @@ EXTRA_DIST = \
configure.ac \
doc/README.Win32.md \
install-sh \
+ instrument-functions.c \
lbl/os-osf4.h \
lbl/os-solaris2.h \
lbl/os-sunos4.h \
diff --git a/config.h.in b/config.h.in
index 6bec1150..bb1a4f6a 100644
--- a/config.h.in
+++ b/config.h.in
@@ -3,6 +3,9 @@
/* Define to 1 if arpa/inet.h declares `ether_ntohost' */
#undef ARPA_INET_H_DECLARES_ETHER_NTOHOST
+/* define if you want to build the instrument functions code */
+#undef ENABLE_INSTRUMENT_FUNCTIONS
+
/* define if you want to build the possibly-buggy SMB printer */
#undef ENABLE_SMB
diff --git a/configure b/configure
index 349e0f6b..86a2b97d 100755
--- a/configure
+++ b/configure
@@ -701,6 +701,7 @@ enable_option_checking
with_gcc
enable_universal
with_smi
+enable_instrument_functions
enable_smb
with_user
with_chroot
@@ -1332,6 +1333,8 @@ Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-universal don't build universal on macOS
+ --enable-instrument-functions
+ enable instrument functions code [default=no]
--enable-smb enable possibly-buggy SMB printer [default=no]
--disable-local-libpcap don't look for a local libpcap [default=check for a
local libpcap]
@@ -4380,6 +4383,31 @@ fi
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable the instrument functions code" >&5
+$as_echo_n "checking whether to enable the instrument functions code... " >&6; }
+# Check whether --enable-instrument-functions was given.
+if test "${enable_instrument_functions+set}" = set; then :
+ enableval=$enable_instrument_functions;
+else
+ enableval=no
+fi
+
+case "$enableval" in
+yes) { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$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"
+ ;;
+*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+esac
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable the possibly-buggy SMB printer" >&5
$as_echo_n "checking whether to enable the possibly-buggy SMB printer... " >&6; }
# Check whether --enable-smb was given.
diff --git a/configure.ac b/configure.ac
index 67970717..6d29d945 100644
--- a/configure.ac
+++ b/configure.ac
@@ -146,6 +146,25 @@ main()
])
fi
+AC_MSG_CHECKING([whether to enable the instrument functions code])
+AC_ARG_ENABLE([instrument-functions],
+ [AS_HELP_STRING([--enable-instrument-functions],
+ [enable instrument functions code [default=no]])],
+ [],
+ [enableval=no])
+case "$enableval" in
+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"
+ ;;
+*) AC_MSG_RESULT(no)
+ ;;
+esac
+
AC_MSG_CHECKING([whether to enable the possibly-buggy SMB printer])
AC_ARG_ENABLE([smb],
[AS_HELP_STRING([--enable-smb],
diff --git a/instrument-functions.c b/instrument-functions.c
new file mode 100644
index 00000000..2541644b
--- /dev/null
+++ b/instrument-functions.c
@@ -0,0 +1,95 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
+#include <stdio.h>
+#include <dlfcn.h>
+
+extern int profile_func_level;
+int profile_func_level = -1;
+
+/*
+ * Generate instrumentation calls for entry and exit to functions.
+ * Just after function entry and just before function exit, the
+ * following profiling functions are called with the address of the
+ * current function and its call site (currently not use).
+ *
+ * The attribute 'no_instrument_function' causes this instrumentation is
+ * not done.
+ *
+ * These profiling functions print the function names with indentation
+ * and call level.
+ *
+ * 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));
+
+void __cyg_profile_func_exit(void *this_fn, void *call_site)
+ __attribute__((no_instrument_function));
+
+/*
+ * The get_function_name() get the function name by calling dladdr()
+ */
+
+static const char *get_function_name(void *func)
+ __attribute__((no_instrument_function));
+
+static const char *
+get_function_name(void *func)
+{
+ Dl_info info;
+ const char *function_name;
+
+ if(dladdr(func, &info))
+ function_name = info.dli_sname;
+ else
+ function_name = NULL;
+ return function_name;
+}
+
+void
+__cyg_profile_func_enter(void *this_fn,
+ void *call_site __attribute__((unused)))
+{
+ int i;
+ const char *function_name;
+
+ if((function_name = get_function_name(this_fn)) != NULL) {
+ profile_func_level += 1;
+ for (i = 0 ; i < profile_func_level ; i++)
+ putchar(' ');
+ printf("[>> %s (%d)]\n", function_name, profile_func_level);
+ }
+ fflush(stdout);
+}
+
+void
+__cyg_profile_func_exit(void *this_fn,
+ void *call_site __attribute__((unused)))
+{
+ int i;
+ const char *function_name;
+
+ if((function_name = get_function_name(this_fn)) != NULL) {
+ for (i = 0 ; i < profile_func_level ; i++)
+ putchar(' ');
+ printf ("[<< %s (%d)]\n", function_name, profile_func_level);
+ profile_func_level -= 1;
+ }
+ fflush(stdout);
+}
diff --git a/print.c b/print.c
index 2e827f71..be487f66 100644
--- a/print.c
+++ b/print.c
@@ -308,6 +308,10 @@ get_if_printer(int type)
return printer;
}
+#ifdef ENABLE_INSTRUMENT_FUNCTIONS
+extern int profile_func_level;
+#endif
+
void
pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
const u_char *sp, u_int packets_captured)
@@ -406,6 +410,10 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
nd_print_trunc(ndo);
/* 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;
+#endif
break;
}
hdrlen = ndo->ndo_ll_hdr_len;