diff --git a/include/haproxy/global-t.h b/include/haproxy/global-t.h index 7665ef24d..6e66a1d81 100644 --- a/include/haproxy/global-t.h +++ b/include/haproxy/global-t.h @@ -217,10 +217,15 @@ struct global { int thread_limit; /* hard limit on the number of threads */ int prealloc_fd; uchar clt_privileged_ports; /* bitmask to allow client privileged ports exchanges per protocol */ - /* 3-bytes hole */ + unsigned char argc; /* cast int argc to unsigned char in order to fill better the previous + * 3 bytes hole, it seems unreal, that oneday we could start with more + * than 255 arguments + */ + /* 2-bytes hole */ int cfg_curr_line; /* line number currently being parsed */ const char *cfg_curr_file; /* config file currently being parsed or NULL */ char *cfg_curr_section; /* config section name currently being parsed or NULL */ + char **argv; /* ptr to array with args */ /* The info above is config stuff, it doesn't change during the process' life */ /* A number of the elements below are updated by all threads in real time and diff --git a/src/debug.c b/src/debug.c index 5f21f0271..a7626b18f 100644 --- a/src/debug.c +++ b/src/debug.c @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -114,6 +115,7 @@ struct post_mortem { gid_t boot_gid; struct rlimit limit_fd; // RLIMIT_NOFILE struct rlimit limit_ram; // RLIMIT_DATA + char **argv; #if defined(USE_THREAD) struct { @@ -121,6 +123,7 @@ struct post_mortem { void *stack_top; // top of the stack } thread_info[MAX_THREADS]; #endif + unsigned char argc; } process; #if defined(HA_HAVE_DUMP_LIBS) @@ -498,12 +501,14 @@ static int debug_parse_cli_show_libs(char **args, char *payload, struct appctx * static int debug_parse_cli_show_dev(char **args, char *payload, struct appctx *appctx, void *private) { const char **build_opt; + int i; if (*args[2]) return cli_err(appctx, "This command takes no argument.\n"); chunk_reset(&trash); + chunk_appendf(&trash, "HAProxy version %s\n", haproxy_version); chunk_appendf(&trash, "Features\n %s\n", build_features); chunk_appendf(&trash, "Build options\n"); @@ -545,8 +550,14 @@ static int debug_parse_cli_show_dev(char **args, char *payload, struct appctx *a chunk_appendf(&trash, "Process info\n"); chunk_appendf(&trash, " pid: %d\n", post_mortem.process.pid); + chunk_appendf(&trash, " cmdline: "); + for (i = 0; i < post_mortem.process.argc; i++) + chunk_appendf(&trash, "%s ", post_mortem.process.argv[i]); + chunk_appendf(&trash, "\n"); chunk_appendf(&trash, " boot uid: %d\n", post_mortem.process.boot_uid); + chunk_appendf(&trash, " runtime uid: %d\n", geteuid()); chunk_appendf(&trash, " boot gid: %d\n", post_mortem.process.boot_gid); + chunk_appendf(&trash, " runtime gid: %d\n", getegid()); if ((ulong)post_mortem.process.limit_fd.rlim_cur != RLIM_INFINITY) chunk_appendf(&trash, " fd limit (soft): %lu\n", (ulong)post_mortem.process.limit_fd.rlim_cur); @@ -2271,6 +2282,8 @@ static int feed_post_mortem() post_mortem.process.pid = getpid(); post_mortem.process.boot_uid = geteuid(); post_mortem.process.boot_gid = getegid(); + post_mortem.process.argc = global.argc; + post_mortem.process.argv = global.argv; getrlimit(RLIMIT_NOFILE, &post_mortem.process.limit_fd); getrlimit(RLIMIT_DATA, &post_mortem.process.limit_ram); diff --git a/src/haproxy.c b/src/haproxy.c index c987fdbfa..afccf0912 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -1557,6 +1557,11 @@ static void init_early(int argc, char **argv) totalconn = actconn = listeners = stopping = 0; killed = pid = 0; + /* cast to one byte in order to fill better a 3 bytes hole in the global struct, + * we hopefully will never start with > than 255 args + */ + global.argc = (unsigned char)argc; + global.argv = argv; global.maxsock = 10; /* reserve 10 fds ; will be incremented by socket eaters */ global.rlimit_memmax_all = HAPROXY_MEMMAX; global.mode = MODE_STARTING;