]> The Tcpdump Group git mirrors - tcpdump/commitdiff
autoconf: Add the option to print functions names (entry and exit)
authorFrancois-Xavier Le Bail <[email protected]>
Mon, 10 Jan 2022 15:37:07 +0000 (16:37 +0100)
committerFrancois-Xavier Le Bail <[email protected]>
Mon, 17 Jan 2022 19:48:57 +0000 (20:48 +0100)
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.

Makefile.in
config.h.in
configure
configure.ac
instrument-functions.c [new file with mode: 0644]
print.c

index 2515e661d395884ed8cdf7aa932547d10f8cd80d..ca30bb3e1df21204a77f8ec089a89e560fd57af6 100644 (file)
@@ -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 \
index 6bec1150926ad9b22221c7cd6d525ec79d613ba2..bb1a4f6adcfc6cdd42f9874a4030c9e40058bdac 100644 (file)
@@ -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
 
index 349e0f6b99fd613ccff978e01d7a061e73c7b38d..86a2b97d71febbc7a27c09c66b2a935cff9f87b0 100755 (executable)
--- 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.
index 679707177e9b8ea6b7b1d3d99b245c1b2094ff8c..6d29d945bd30c29f1c7cd7a6f0dbd2202cb96cf1 100644 (file)
@@ -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 (file)
index 0000000..2541644
--- /dev/null
@@ -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 2e827f71fccc7ca8b06a36fce207c6230c8731a8..be487f661cde496eca6cc69955995cfa0f9eb9d9 100644 (file)
--- 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;