mirror of
https://github.com/haproxy/haproxy.git
synced 2026-06-08 16:23:24 -04:00
MINOR: debug: add -dA to dump an archive of all dependencies
This adds "-dA[file]" on the command line, which dumps an archive of all dependencies detected at runtime into the designated file in tar format. This is equivalent to "set-dumpable libs", but instead of keeping the libs in memory, it dumps them into a file. This may be used after a core dump, in order to provide all necessary libraries to developers to permit them to exploit the core. This may not be available on all operating systems.
This commit is contained in:
parent
f8fd6d25d8
commit
030a2bfeeb
5 changed files with 82 additions and 0 deletions
|
|
@ -215,6 +215,18 @@ list of options is :
|
|||
in foreground and to show incoming and outgoing events. It must never be
|
||||
used in an init script.
|
||||
|
||||
-dA[file] : dump an archive of all dependencies detected at boot time in the
|
||||
designated file in tar format, immediately after the configuration is done
|
||||
loading. This is equivalent to "set-dumpable libs", but instead of keeping
|
||||
the libs in memory, it dumps them into a file. This may be used after a
|
||||
core dump, in order to provide all necessary libraries to developers to
|
||||
permit them to exploit the core. This may not be available on all operating
|
||||
systems. It is highly recommended to use this with the regular
|
||||
configuration files, and optionally with "-c" when used manually, to make
|
||||
haproxy immediately exit after the dump, without starting. Example:
|
||||
|
||||
$ haproxy -dA/tmp/libs.tar -c -f /etc/haproxy/haproxy.cfg
|
||||
|
||||
-dC[key] : dump the configuration file. It is performed after the lines are
|
||||
tokenized, so comments are stripped and indenting is forced. If a non-zero
|
||||
key is specified, lines are truncated before sensitive/confidential fields,
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ extern struct cfgfile fileless_cfg;
|
|||
/* storage for collected libs */
|
||||
extern void *lib_storage;
|
||||
extern size_t lib_size;
|
||||
extern char *lib_output_file;
|
||||
|
||||
struct proxy;
|
||||
struct server;
|
||||
|
|
|
|||
|
|
@ -1155,6 +1155,7 @@ void *get_sym_next_addr(const char *name);
|
|||
int dump_libs(struct buffer *output, int with_addr);
|
||||
void collect_libs(void);
|
||||
void free_collected_libs(void);
|
||||
int copy_libs_to_file(void);
|
||||
|
||||
/* Note that this may result in opening libgcc() on first call, so it may need
|
||||
* to have been called once before chrooting.
|
||||
|
|
|
|||
|
|
@ -274,6 +274,7 @@ unsigned int deprecated_directives_allowed = 0;
|
|||
/* mapped storage for collected libs */
|
||||
void *lib_storage = NULL;
|
||||
size_t lib_size = 0;
|
||||
char *lib_output_file = NULL;
|
||||
|
||||
int check_kw_experimental(struct cfg_keyword *kw, const char *file, int linenum,
|
||||
char **errmsg)
|
||||
|
|
@ -784,6 +785,9 @@ static void usage(char *name)
|
|||
#if defined(HA_HAVE_DUMP_LIBS)
|
||||
" -dL dumps loaded object files after config checks\n"
|
||||
#endif
|
||||
#if defined(HA_HAVE_DUMP_LIBS) && defined(HA_HAVE_DL_ITERATE_PHDR)
|
||||
" -dA[file] collects libs into a tar file at <file>\n"
|
||||
#endif
|
||||
#if defined(USE_CPU_AFFINITY)
|
||||
" -dc dumps the list of selected and evicted CPUs\n"
|
||||
#endif
|
||||
|
|
@ -1627,6 +1631,16 @@ void haproxy_init_args(int argc, char **argv)
|
|||
#if defined(HA_HAVE_DUMP_LIBS)
|
||||
else if (*flag == 'd' && flag[1] == 'L')
|
||||
arg_mode |= MODE_DUMP_LIBS;
|
||||
# if defined(HA_HAVE_DL_ITERATE_PHDR)
|
||||
else if (*flag == 'd' && flag[1] == 'A') {
|
||||
lib_output_file = flag + 2;
|
||||
if (!*lib_output_file) {
|
||||
ha_alert("-dA: missing output file name\n");
|
||||
exit(1);
|
||||
}
|
||||
arg_mode |= MODE_DUMP_LIBS; // stop on libs dump
|
||||
}
|
||||
# endif /* HA_HAVE_DL_ITERATE_PHDR */
|
||||
#endif
|
||||
else if (*flag == 'd' && flag[1] == 'K') {
|
||||
arg_mode |= MODE_DUMP_KWD;
|
||||
|
|
@ -2312,6 +2326,17 @@ static void step_init_2(int argc, char** argv)
|
|||
|
||||
#if defined(HA_HAVE_DUMP_LIBS)
|
||||
if (global.mode & MODE_DUMP_LIBS && !master) {
|
||||
# if defined(HA_HAVE_DL_ITERATE_PHDR)
|
||||
if (lib_output_file) {
|
||||
/* we'll dump everything to lib_output_file */
|
||||
if (copy_libs_to_file() < 0)
|
||||
deinit_and_exit(1);
|
||||
/* release memory if no longer needed */
|
||||
if ((global.tune.options & (GTUNE_SET_DUMPABLE | GTUNE_COLLECT_LIBS)) !=
|
||||
(GTUNE_SET_DUMPABLE | GTUNE_COLLECT_LIBS))
|
||||
free_collected_libs();
|
||||
}
|
||||
# endif
|
||||
qfprintf(stdout, "List of loaded object files:\n");
|
||||
chunk_reset(&trash);
|
||||
if (dump_libs(&trash, ((arg_mode & (MODE_QUIET|MODE_VERBOSE)) == MODE_VERBOSE)))
|
||||
|
|
|
|||
43
src/tools.c
43
src/tools.c
|
|
@ -6101,6 +6101,10 @@ void collect_libs(void)
|
|||
void *page;
|
||||
int i;
|
||||
|
||||
/* already done */
|
||||
if (lib_storage)
|
||||
return;
|
||||
|
||||
/* prepend a directory named after the starting pid */
|
||||
snprintf(dir_name, sizeof(dir_name), "core-%u", getpid());
|
||||
ctx.prefix = dir_name;
|
||||
|
|
@ -6162,6 +6166,39 @@ void free_collected_libs(void)
|
|||
lib_size = 0;
|
||||
}
|
||||
|
||||
/* Prepare the archive in RAM and copy it to a target file. Returns <0 upon error. */
|
||||
int copy_libs_to_file(void)
|
||||
{
|
||||
ssize_t len;
|
||||
int ret = -1;
|
||||
int fd = -1;
|
||||
|
||||
fd = open(lib_output_file, O_CREAT | O_WRONLY, S_IRWXU);
|
||||
if (fd < 0) {
|
||||
ha_alert("Cannot create output file to dump dependencies: %s.\n", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
collect_libs();
|
||||
if (!lib_storage || !lib_size) {
|
||||
ha_alert("Failed to collect dependencies.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
len = write(fd, lib_storage, lib_size);
|
||||
if (len != lib_size) {
|
||||
ha_alert("Failed to write dependencies to output file: %s.\n", strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* OK done */
|
||||
ret = 0;
|
||||
fail:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
# else // no DL_ITERATE_PHDR
|
||||
# error "No dump_libs() function for this platform"
|
||||
# endif
|
||||
|
|
@ -6183,6 +6220,12 @@ void free_collected_libs(void)
|
|||
{
|
||||
}
|
||||
|
||||
/* unsupported platform: do not copy anything */
|
||||
int copy_libs_to_file(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif // HA_HAVE_DUMP_LIBS
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue