]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: debug: add support for -dL to dump library names at boot
authorWilly Tarreau <w@1wt.eu>
Tue, 28 Dec 2021 14:43:11 +0000 (15:43 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 28 Dec 2021 16:07:13 +0000 (17:07 +0100)
This is a second help to dump loaded library names late at boot, once
external code has already been initialized. The purpose is to provide
a format that makes it easy to pass to "tar" to produce an archive
containing the executable and the list of dependencies. For example
if haproxy is started as "haproxy -f foo.cfg", a config check only
will suffice to quit before starting, "-q" will be used to disable
undesired output messages, and -dL will be use to dump libraries.
This will result in such a command to trivially produce a tarball
of loaded libraries:

   ./haproxy -q -c -dL -f foo.cfg | tar -T - -hzcf archive.tgz

doc/management.txt
include/haproxy/global-t.h
src/haproxy.c

index 36456d5185e4cddcb251bab67976c443336877b6..147e059f6db198f61fd8a0d493abb13ad97337e0 100644 (file)
@@ -213,6 +213,19 @@ list of options is :
     getaddrinfo() exist on various systems and cause anomalies that are
     difficult to troubleshoot.
 
+  -dL : dumps the list of dynamic shared libraries that are loaded at the end
+   of the config processing. This will generally also include deep dependencies
+   such as anything loaded from Lua code for example, as well as the executable
+   itself. The list is printed in a format that ought to be easy enough to
+   sanitize to directly produce a tarball of all dependencies. Since it doesn't
+   stop the program's startup, it is recommended to only use it in combination
+   with "-c" and "-q" where only the list of loaded objects will be displayed
+   (or nothing in case of error). In addition, keep in mind that when providing
+   such a package to help with a core file analysis, most libraries are in fact
+   symbolic links that need to be dereferenced when creating the archive:
+
+       ./haproxy -W -q -c -dL -f foo.cfg | tar -T - -hzcf archive.tgz
+
   -dM[<byte>] : forces memory poisoning, which means that each and every
     memory region allocated with malloc() or pool_alloc() will be filled with
     <byte> before being passed to the caller. When <byte> is not specified, it
index fb01e07687e0d62135e8a76db35b1f5e58d99b15..44eed88f7287bb99977c19a280a7bc469762124b 100644 (file)
@@ -40,6 +40,7 @@
 #define        MODE_DIAG       0x400   /* extra warnings */
 #define        MODE_CHECK_CONDITION    0x800    /* -cc mode */
 #define        MODE_STOPPING   0x1000  /* the process is in the deinit phase, the event loop is not running anymore. */
+#define        MODE_DUMP_LIBS  0x2000  /* dump loaded libraries at the end of init phase */
 
 /* list of last checks to perform, depending on config options */
 #define LSTCHK_CAP_BIND        0x00000001      /* check that we can bind to any port */
index dda03a9946a7d002ef98bdf397aa205253633aaf..ba91d34fe1707f33d0cabebdddbcd35e847ebe9a 100644 (file)
@@ -596,6 +596,9 @@ static void usage(char *name)
 #endif
 #if defined(SO_REUSEPORT)
                "        -dR disables SO_REUSEPORT usage\n"
+#endif
+#if defined(HA_HAVE_DUMP_LIBS)
+               "        -dL dumps loaded object files after config checks\n"
 #endif
                "        -dr ignores server address resolution failures\n"
                "        -dV disables SSL verify on servers side\n"
@@ -1632,6 +1635,10 @@ static void init(int argc, char **argv)
                                mem_poison_byte = flag[2] ? strtol(flag + 2, NULL, 0) : 'P';
                        else if (*flag == 'd' && flag[1] == 'r')
                                global.tune.options |= GTUNE_RESOLVE_DONTFAIL;
+#if defined(HA_HAVE_DUMP_LIBS)
+                       else if (*flag == 'd' && flag[1] == 'L')
+                               arg_mode |= MODE_DUMP_LIBS;
+#endif
                        else if (*flag == 'd')
                                arg_mode |= MODE_DEBUG;
                        else if (*flag == 'c' && flag[1] == 'c') {
@@ -1773,7 +1780,7 @@ static void init(int argc, char **argv)
 
        global.mode |= (arg_mode & (MODE_DAEMON | MODE_MWORKER | MODE_FOREGROUND | MODE_VERBOSE
                                    | MODE_QUIET | MODE_CHECK | MODE_DEBUG | MODE_ZERO_WARNING
-                                   | MODE_DIAG | MODE_CHECK_CONDITION));
+                                   | MODE_DIAG | MODE_CHECK_CONDITION | MODE_DUMP_LIBS));
 
        if (getenv("HAPROXY_MWORKER_WAIT_ONLY")) {
                unsetenv("HAPROXY_MWORKER_WAIT_ONLY");
@@ -2056,6 +2063,15 @@ static void init(int argc, char **argv)
                exit(1);
        }
 
+#if defined(HA_HAVE_DUMP_LIBS)
+       if (global.mode & MODE_DUMP_LIBS) {
+               qfprintf(stdout, "List of loaded object files:\n");
+               chunk_reset(&trash);
+               if (dump_libs(&trash, 0))
+                       printf("%s", trash.area);
+       }
+#endif
+
        if (global.mode & MODE_CHECK) {
                struct peers *pr;
                struct proxy *px;