From 6e7bb4d3e3f9a01a04d5a476577d26ebab172a71 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 18 Jul 2025 01:12:31 +0900 Subject: [PATCH 1/6] analyze: add missing full stop in the log message Follow-up for 9a08000d186396bc8bcb8fe057720417543c3bf0 and ad6e02e7b42db35178305614e643be7a62568d87. --- src/analyze/analyze-unit-gdb.c | 4 ++-- src/analyze/analyze-unit-shell.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/analyze/analyze-unit-gdb.c b/src/analyze/analyze-unit-gdb.c index 92b8a5cb5b..fc06f86030 100644 --- a/src/analyze/analyze-unit-gdb.c +++ b/src/analyze/analyze-unit-gdb.c @@ -32,7 +32,7 @@ int verb_unit_gdb(int argc, char *argv[], void *userdata) { int r; if (arg_transport != BUS_TRANSPORT_LOCAL) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot spawn a debugger for a remote service"); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot spawn a debugger for a remote service."); r = unit_name_mangle_with_suffix(argv[1], "as unit", UNIT_NAME_MANGLE_WARN, ".service", &unit); if (r < 0) @@ -72,7 +72,7 @@ int verb_unit_gdb(int argc, char *argv[], void *userdata) { return log_oom(); if (!STR_IN_SET(arg_debugger, "gdb", "lldb")) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The debugger must be either 'gdb' or 'lldb'"); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The debugger must be either 'gdb' or 'lldb'."); if (streq(arg_debugger, "gdb")) { r = strv_extendf(&debugger_call, "--pid=" PID_FMT, pid); diff --git a/src/analyze/analyze-unit-shell.c b/src/analyze/analyze-unit-shell.c index 6d241eb6e1..6990aa6d9b 100644 --- a/src/analyze/analyze-unit-shell.c +++ b/src/analyze/analyze-unit-shell.c @@ -28,7 +28,7 @@ int verb_unit_shell(int argc, char *argv[], void *userdata) { int r; if (arg_transport != BUS_TRANSPORT_LOCAL) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot spawn a unit shell for a remote service"); + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot spawn a unit shell for a remote service."); r = unit_name_mangle_with_suffix(argv[1], "as unit", UNIT_NAME_MANGLE_WARN, ".service", &unit); if (r < 0) From 33502785de3075b5a42d7df436931da46b01ba86 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 18 Jul 2025 01:13:44 +0900 Subject: [PATCH 2/6] analyze-unit-shell: drop unnecessary error check execl() and friends will not return on success. Follow-up for 9a08000d186396bc8bcb8fe057720417543c3bf0. --- src/analyze/analyze-unit-shell.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/analyze/analyze-unit-shell.c b/src/analyze/analyze-unit-shell.c index 6990aa6d9b..43eb65932e 100644 --- a/src/analyze/analyze-unit-shell.c +++ b/src/analyze/analyze-unit-shell.c @@ -95,23 +95,22 @@ int verb_unit_shell(int argc, char *argv[], void *userdata) { if (r == 0) { if (args) { - r = execvp(args[0], args); - if (r < 0) - log_error_errno(errno, "Failed to execute '%s': %m", *args); + (void) execvp(args[0], args); + log_error_errno(errno, "Failed to execute '%s': %m", *args); } else { - r = execl(DEFAULT_USER_SHELL, "-" DEFAULT_USER_SHELL_NAME, NULL); - if (r < 0) - log_debug_errno(errno, "Failed to execute '" DEFAULT_USER_SHELL "', ignoring: %m"); + (void) execl(DEFAULT_USER_SHELL, "-" DEFAULT_USER_SHELL_NAME, NULL); + log_debug_errno(errno, "Failed to execute '" DEFAULT_USER_SHELL "', ignoring: %m"); + if (!streq(DEFAULT_USER_SHELL, "/bin/bash")) { - r = execl("/bin/bash", "-bash", NULL); - if (r < 0) - log_debug_errno(errno, "Failed to execute '/bin/bash', ignoring: %m"); + (void) execl("/bin/bash", "-bash", NULL); + log_debug_errno(errno, "Failed to execute '/bin/bash', ignoring: %m"); } + if (!streq(DEFAULT_USER_SHELL, "/bin/sh")) { - r = execl("/bin/sh", "-sh", NULL); - if (r < 0) - log_debug_errno(errno, "Failed to execute '/bin/sh', ignoring: %m"); + (void) execl("/bin/sh", "-sh", NULL); + log_debug_errno(errno, "Failed to execute '/bin/sh', ignoring: %m"); } + log_error_errno(errno, "Failed to execute '" DEFAULT_USER_SHELL "', '/bin/bash', and '/bin/sh': %m"); } _exit(EXIT_FAILURE); From 3bfc3414e606c82f7196a234ac7df8905320252e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 18 Jul 2025 01:20:18 +0900 Subject: [PATCH 3/6] analyze: fix memleak and missing oom check Follow-up for ad6e02e7b42db35178305614e643be7a62568d87. --- src/analyze/analyze-unit-gdb.c | 7 +++++-- src/analyze/analyze.c | 10 +++++++--- src/analyze/analyze.h | 3 ++- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/analyze/analyze-unit-gdb.c b/src/analyze/analyze-unit-gdb.c index fc06f86030..85e7488ca0 100644 --- a/src/analyze/analyze-unit-gdb.c +++ b/src/analyze/analyze-unit-gdb.c @@ -63,8 +63,11 @@ int verb_unit_gdb(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to read the main PID of %s from reply: %m", unit); - if (!arg_debugger) - arg_debugger = secure_getenv("SYSTEMD_DEBUGGER") ?: "gdb"; + if (!arg_debugger) { + arg_debugger = strdup(secure_getenv("SYSTEMD_DEBUGGER") ?: "gdb"); + if (!arg_debugger) + return log_oom(); + } _cleanup_strv_free_ char **debugger_call = NULL; r = strv_extend(&debugger_call, arg_debugger); diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 762317a653..d76c09b520 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -81,8 +81,8 @@ usec_t arg_fuzz = 0; PagerFlags arg_pager_flags = 0; CatFlags arg_cat_flags = 0; BusTransport arg_transport = BUS_TRANSPORT_LOCAL; -const char *arg_debugger = NULL; -static char **arg_debugger_args = NULL; +char *arg_debugger = NULL; +char **arg_debugger_args = NULL; const char *arg_host = NULL; RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM; RecursiveErrors arg_recursive_errors = _RECURSIVE_ERRORS_INVALID; @@ -109,6 +109,8 @@ char *arg_drm_device_path = NULL; STATIC_DESTRUCTOR_REGISTER(arg_dot_from_patterns, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_dot_to_patterns, strv_freep); +STATIC_DESTRUCTOR_REGISTER(arg_debugger, freep); +STATIC_DESTRUCTOR_REGISTER(arg_debugger_args, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep); STATIC_DESTRUCTOR_REGISTER(arg_security_policy, freep); @@ -665,7 +667,9 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_DEBUGGER: - arg_debugger = strdup(optarg); + r = free_and_strdup_warn(&arg_debugger, optarg); + if (r < 0) + return r; break; case 'A': { diff --git a/src/analyze/analyze.h b/src/analyze/analyze.h index 1d489b723e..d5b7bfcb82 100644 --- a/src/analyze/analyze.h +++ b/src/analyze/analyze.h @@ -24,7 +24,8 @@ extern PagerFlags arg_pager_flags; extern CatFlags arg_cat_flags; extern BusTransport arg_transport; extern const char *arg_host; -extern const char *arg_debugger; +extern char *arg_debugger; +extern char **arg_debugger_args; extern RuntimeScope arg_runtime_scope; extern RecursiveErrors arg_recursive_errors; extern bool arg_man; From ff4c911ffd3f67875fabb41bcbd192af015116a5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 18 Jul 2025 01:29:05 +0900 Subject: [PATCH 4/6] analyze: merge if branches on debugger No functional changes, just refactoring. --- src/analyze/analyze-unit-gdb.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/analyze/analyze-unit-gdb.c b/src/analyze/analyze-unit-gdb.c index 85e7488ca0..06b5fa7453 100644 --- a/src/analyze/analyze-unit-gdb.c +++ b/src/analyze/analyze-unit-gdb.c @@ -69,39 +69,39 @@ int verb_unit_gdb(int argc, char *argv[], void *userdata) { return log_oom(); } + if (!STR_IN_SET(arg_debugger, "gdb", "lldb")) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The debugger must be either 'gdb' or 'lldb'."); + _cleanup_strv_free_ char **debugger_call = NULL; r = strv_extend(&debugger_call, arg_debugger); if (r < 0) return log_oom(); - if (!STR_IN_SET(arg_debugger, "gdb", "lldb")) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The debugger must be either 'gdb' or 'lldb'."); - if (streq(arg_debugger, "gdb")) { r = strv_extendf(&debugger_call, "--pid=" PID_FMT, pid); if (r < 0) return log_oom(); - } - if (streq(arg_debugger, "lldb")) { - r = strv_extendf(&debugger_call, "--attach-pid=" PID_FMT, pid); - if (r < 0) - return log_oom(); - } - - if (arg_root) { - if (streq(arg_debugger, "gdb")) { + if (arg_root) { _cleanup_free_ char *sysroot_cmd = strjoin("set sysroot ", arg_root); r = strv_extend_many(&debugger_call, "-iex", sysroot_cmd); if (r < 0) return log_oom(); - } else if (streq(arg_debugger, "lldb")) { + } + + } else if (streq(arg_debugger, "lldb")) { + r = strv_extendf(&debugger_call, "--attach-pid=" PID_FMT, pid); + if (r < 0) + return log_oom(); + + if (arg_root) { _cleanup_free_ char *sysroot_cmd = strjoin("platform select --sysroot ", arg_root, " host"); r = strv_extend_many(&debugger_call, "-O", sysroot_cmd); if (r < 0) return log_oom(); } - } + } else + assert_not_reached(); /* Don't interfere with debugger and its handling of SIGINT. */ (void) ignore_signals(SIGINT); From 1b25aa7f6e26ad30e7e6c595fc9490b5d131c412 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 18 Jul 2025 01:29:59 +0900 Subject: [PATCH 5/6] analyze-unit-gdb: append debugger arguments Previously, the --debugger-arguments= was ignored. Follow-up for ad6e02e7b42db35178305614e643be7a62568d87. --- src/analyze/analyze-unit-gdb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/analyze/analyze-unit-gdb.c b/src/analyze/analyze-unit-gdb.c index 06b5fa7453..7c5da0b948 100644 --- a/src/analyze/analyze-unit-gdb.c +++ b/src/analyze/analyze-unit-gdb.c @@ -103,6 +103,10 @@ int verb_unit_gdb(int argc, char *argv[], void *userdata) { } else assert_not_reached(); + r = strv_extend_strv(&debugger_call, arg_debugger_args, /* filter_duplicates = */ false); + if (r < 0) + return log_oom(); + /* Don't interfere with debugger and its handling of SIGINT. */ (void) ignore_signals(SIGINT); (void) sigaction(SIGTERM, &sa, NULL); From 54820da421a6d4ed6afbc76f5c718ae02e65c525 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 18 Jul 2025 01:44:25 +0900 Subject: [PATCH 6/6] bash-completion/analyze: show candidates for --debugger This also adds missing completion for --debugger-arguments. Follow-up for ad6e02e7b42db35178305614e643be7a62568d87. --- shell-completion/bash/systemd-analyze | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze index d3d3fe4c63..3eeeffd241 100644 --- a/shell-completion/bash/systemd-analyze +++ b/shell-completion/bash/systemd-analyze @@ -62,8 +62,9 @@ _systemd_analyze() { local -A OPTS=( [STANDALONE]='-h --help --version --system --user --global --order --require --no-pager - --man=no --generators=yes -q --quiet' - [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern --root --debugger' + --man=no --generators=yes -q --quiet' + [ARG]='-H --host -M --machine --fuzz --from-pattern --to-pattern --root --debugger + -A --debugger-arguments' ) local -A VERBS=( @@ -116,6 +117,12 @@ _systemd_analyze() { --machine|-M) comps=$( __get_machines ) ;; + --debugger) + comps="gdb lldb" + ;; + *) + return 0 + ;; esac COMPREPLY=( $(compgen -W '$comps' -- "$cur") ) return 0