MINOR: cli/debug: show dev: add cmdline and version

'show dev' command is very convenient to obtain haproxy debugging information,
while process is run in container. Let's extend its output with version and
cmdline. cmdline is useful in a way, as it shows absolute binary path and its
arguments, because sometimes the person, who is debugging failing container is
not the same, who has created and deployed it.

argc and argv are stored in the exported global structure, because
feed_post_mortem() is added as a post check function callback in the
post_check_list. So we can't simply change the signature of
feed_post_mortem(), without breaking other post check callbacks APIs.

Parsers are not supposed to modify argv, so we can safely bypass its pointer
to debug_parse_cli_show_dev(), without copying all argument stings somewhere
in the heap or on stack.
This commit is contained in:
Valentine Krasnobaeva 2024-05-29 11:27:21 +02:00 committed by Willy Tarreau
parent fba9ade891
commit 0d79c9bedf
3 changed files with 24 additions and 1 deletions

View File

@ -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

View File

@ -47,6 +47,7 @@
#include <haproxy/time.h>
#include <haproxy/tools.h>
#include <haproxy/trace.h>
#include <haproxy/version.h>
#include <import/ist.h>
@ -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);

View File

@ -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;