Bug Summary

File:build-scan/../src/coredump/coredumpctl.c
Warning:line 443, column 17
Potential leak of memory pointed to by 'filename'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name coredumpctl.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I coredumpctl.p -I . -I .. -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/coredump/coredumpctl.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <fcntl.h>
4#include <getopt.h>
5#include <locale.h>
6#include <stdio.h>
7#include <string.h>
8#include <unistd.h>
9
10#include "sd-bus.h"
11#include "sd-journal.h"
12#include "sd-messages.h"
13
14#include "alloc-util.h"
15#include "bus-error.h"
16#include "bus-util.h"
17#include "compress.h"
18#include "fd-util.h"
19#include "fileio.h"
20#include "fs-util.h"
21#include "journal-internal.h"
22#include "journal-util.h"
23#include "log.h"
24#include "macro.h"
25#include "pager.h"
26#include "parse-util.h"
27#include "path-util.h"
28#include "process-util.h"
29#include "sigbus.h"
30#include "signal-util.h"
31#include "string-util.h"
32#include "strv.h"
33#include "terminal-util.h"
34#include "user-util.h"
35#include "util.h"
36#include "verbs.h"
37
38#define SHORT_BUS_CALL_TIMEOUT_USEC(3 * ((usec_t) 1000000ULL)) (3 * USEC_PER_SEC((usec_t) 1000000ULL))
39
40static usec_t arg_since = USEC_INFINITY((usec_t) -1), arg_until = USEC_INFINITY((usec_t) -1);
41static const char* arg_field = NULL((void*)0);
42static const char *arg_debugger = NULL((void*)0);
43static const char *arg_directory = NULL((void*)0);
44static bool_Bool arg_no_pager = false0;
45static int arg_no_legend = false0;
46static int arg_one = false0;
47static FILE* arg_output = NULL((void*)0);
48static bool_Bool arg_reverse = false0;
49static bool_Bool arg_quiet = false0;
50
51static int add_match(sd_journal *j, const char *match) {
52 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0);
53 const char* prefix, *pattern;
54 pid_t pid;
55 int r;
56
57 if (strchr(match, '='))
58 prefix = "";
59 else if (strchr(match, '/')) {
60 r = path_make_absolute_cwd(match, &p);
61 if (r < 0)
62 return log_error_errno(r, "path_make_absolute_cwd(\"%s\"): %m", match)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 62, __func__, "path_make_absolute_cwd(\"%s\"): %m"
, match) : -abs(_e); })
;
63
64 match = p;
65 prefix = "COREDUMP_EXE=";
66 } else if (parse_pid(match, &pid) >= 0)
67 prefix = "COREDUMP_PID=";
68 else
69 prefix = "COREDUMP_COMM=";
70
71 pattern = strjoina(prefix, match)({ const char *_appendees_[] = { prefix, match }; char *_d_, *
_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
72 log_debug("Adding match: %s", pattern)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 72, __func__, "Adding match: %s"
, pattern) : -abs(_e); })
;
73 r = sd_journal_add_match(j, pattern, 0);
74 if (r < 0)
75 return log_error_errno(r, "Failed to add match \"%s\": %m", match)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 75, __func__, "Failed to add match \"%s\": %m"
, match) : -abs(_e); })
;
76
77 return 0;
78}
79
80static int add_matches(sd_journal *j, char **matches) {
81 char **match;
82 int r;
83
84 r = sd_journal_add_match(j, "MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR"fc" "2e" "22" "bc" "6e" "e6" "47" "b6" "b9" "07" "29" "ab" "34"
"a2" "50" "b1"
, 0);
85 if (r < 0)
86 return log_error_errno(r, "Failed to add match \"%s\": %m", "MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 86, __func__, "Failed to add match \"%s\": %m"
, "MESSAGE_ID=" "fc" "2e" "22" "bc" "6e" "e6" "47" "b6" "b9" "07"
"29" "ab" "34" "a2" "50" "b1") : -abs(_e); })
;
87
88 r = sd_journal_add_match(j, "MESSAGE_ID=" SD_MESSAGE_BACKTRACE_STR"1f" "4e" "0a" "44" "a8" "86" "49" "93" "9a" "ae" "a3" "4f" "c6"
"da" "8c" "95"
, 0);
89 if (r < 0)
90 return log_error_errno(r, "Failed to add match \"%s\": %m", "MESSAGE_ID=" SD_MESSAGE_BACKTRACE_STR)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 90, __func__, "Failed to add match \"%s\": %m"
, "MESSAGE_ID=" "1f" "4e" "0a" "44" "a8" "86" "49" "93" "9a" "ae"
"a3" "4f" "c6" "da" "8c" "95") : -abs(_e); })
;
91
92 STRV_FOREACH(match, matches)for ((match) = (matches); (match) && *(match); (match
)++)
{
93 r = add_match(j, *match);
94 if (r < 0)
95 return r;
96 }
97
98 return 0;
99}
100
101static int acquire_journal(sd_journal **ret, char **matches) {
102 _cleanup_(sd_journal_closep)__attribute__((cleanup(sd_journal_closep))) sd_journal *j = NULL((void*)0);
103 int r;
104
105 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/coredump/coredumpctl.c",
105, __PRETTY_FUNCTION__); } while (0)
;
106
107 if (arg_directory) {
108 r = sd_journal_open_directory(&j, arg_directory, 0);
109 if (r < 0)
110 return log_error_errno(r, "Failed to open journals in directory: %s: %m", arg_directory)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 110, __func__, "Failed to open journals in directory: %s: %m"
, arg_directory) : -abs(_e); })
;
111 } else {
112 r = sd_journal_open(&j, SD_JOURNAL_LOCAL_ONLY);
113 if (r < 0)
114 return log_error_errno(r, "Failed to open journal: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 114, __func__, "Failed to open journal: %m"
) : -abs(_e); })
;
115 }
116
117 r = journal_access_check_and_warn(j, arg_quiet, true1);
118 if (r < 0)
119 return r;
120
121 r = add_matches(j, matches);
122 if (r < 0)
123 return r;
124
125 if (DEBUG_LOGGING(__builtin_expect(!!(log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= 7),0))
) {
126 _cleanup_free___attribute__((cleanup(freep))) char *filter;
127
128 filter = journal_make_match_string(j);
129 log_debug("Journal filter: %s", filter)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 129, __func__, "Journal filter: %s"
, filter) : -abs(_e); })
;
130 }
131
132 *ret = TAKE_PTR(j)({ typeof(j) _ptr_ = (j); (j) = ((void*)0); _ptr_; });
133
134 return 0;
135}
136
137static int help(void) {
138 printf("%s [OPTIONS...]\n\n"
139 "List or retrieve coredumps from the journal.\n\n"
140 "Flags:\n"
141 " -h --help Show this help\n"
142 " --version Print version string\n"
143 " --no-pager Do not pipe output into a pager\n"
144 " --no-legend Do not print the column headers\n"
145 " --debugger=DEBUGGER Use the given debugger\n"
146 " -1 Show information about most recent entry only\n"
147 " -S --since=DATE Only print coredumps since the date\n"
148 " -U --until=DATE Only print coredumps until the date\n"
149 " -r --reverse Show the newest entries first\n"
150 " -F --field=FIELD List all values a certain field takes\n"
151 " -o --output=FILE Write output to FILE\n"
152 " -D --directory=DIR Use journal files from directory\n\n"
153 " -q --quiet Do not show info messages and privilege warning\n"
154 "Commands:\n"
155 " list [MATCHES...] List available coredumps (default)\n"
156 " info [MATCHES...] Show detailed information about one or more coredumps\n"
157 " dump [MATCHES...] Print first matching coredump to stdout\n"
158 " debug [MATCHES...] Start a debugger for the first matching coredump\n"
159 , program_invocation_short_name);
160
161 return 0;
162}
163
164static int parse_argv(int argc, char *argv[]) {
165 enum {
166 ARG_VERSION = 0x100,
167 ARG_NO_PAGER,
168 ARG_NO_LEGEND,
169 ARG_DEBUGGER,
170 };
171
172 int c, r;
173
174 static const struct option options[] = {
175 { "help", no_argument0, NULL((void*)0), 'h' },
176 { "version" , no_argument0, NULL((void*)0), ARG_VERSION },
177 { "no-pager", no_argument0, NULL((void*)0), ARG_NO_PAGER },
178 { "no-legend", no_argument0, NULL((void*)0), ARG_NO_LEGEND },
179 { "debugger", required_argument1, NULL((void*)0), ARG_DEBUGGER },
180 { "output", required_argument1, NULL((void*)0), 'o' },
181 { "field", required_argument1, NULL((void*)0), 'F' },
182 { "directory", required_argument1, NULL((void*)0), 'D' },
183 { "reverse", no_argument0, NULL((void*)0), 'r' },
184 { "since", required_argument1, NULL((void*)0), 'S' },
185 { "until", required_argument1, NULL((void*)0), 'U' },
186 { "quiet", no_argument0, NULL((void*)0), 'q' },
187 {}
188 };
189
190 assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/coredump/coredumpctl.c"
, 190, __PRETTY_FUNCTION__); } while (0)
;
191 assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("argv"), "../src/coredump/coredumpctl.c"
, 191, __PRETTY_FUNCTION__); } while (0)
;
192
193 while ((c = getopt_long(argc, argv, "ho:F:1D:rS:U:q", options, NULL((void*)0))) >= 0)
194 switch(c) {
195 case 'h':
196 return help();
197
198 case ARG_VERSION:
199 return version();
200
201 case ARG_NO_PAGER:
202 arg_no_pager = true1;
203 break;
204
205 case ARG_NO_LEGEND:
206 arg_no_legend = true1;
207 break;
208
209 case ARG_DEBUGGER:
210 arg_debugger = optarg;
211 break;
212
213 case 'o':
214 if (arg_output) {
215 log_error("Cannot set output more than once.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 215, __func__, "Cannot set output more than once."
) : -abs(_e); })
;
216 return -EINVAL22;
217 }
218
219 arg_output = fopen(optarg, "we");
220 if (!arg_output)
221 return log_error_errno(errno, "writing to '%s': %m", optarg)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/coredump/coredumpctl.c", 221, __func__
, "writing to '%s': %m", optarg) : -abs(_e); })
;
222
223 break;
224
225 case 'S':
226 r = parse_timestamp(optarg, &arg_since);
227 if (r < 0)
228 return log_error_errno(r, "Failed to parse timestamp: %s", optarg)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 228, __func__, "Failed to parse timestamp: %s"
, optarg) : -abs(_e); })
;
229 break;
230
231 case 'U':
232 r = parse_timestamp(optarg, &arg_until);
233 if (r < 0)
234 return log_error_errno(r, "Failed to parse timestamp: %s", optarg)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 234, __func__, "Failed to parse timestamp: %s"
, optarg) : -abs(_e); })
;
235 break;
236
237 case 'F':
238 if (arg_field) {
239 log_error("Cannot use --field/-F more than once.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 239, __func__, "Cannot use --field/-F more than once."
) : -abs(_e); })
;
240 return -EINVAL22;
241 }
242 arg_field = optarg;
243 break;
244
245 case '1':
246 arg_one = true1;
247 break;
248
249 case 'D':
250 arg_directory = optarg;
251 break;
252
253 case 'r':
254 arg_reverse = true1;
255 break;
256
257 case 'q':
258 arg_quiet = true1;
259 break;
260
261 case '?':
262 return -EINVAL22;
263
264 default:
265 assert_not_reached("Unhandled option")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unhandled option"), "../src/coredump/coredumpctl.c", 265, __PRETTY_FUNCTION__
); } while (0)
;
266 }
267
268 if (arg_since != USEC_INFINITY((usec_t) -1) && arg_until != USEC_INFINITY((usec_t) -1) &&
269 arg_since > arg_until) {
270 log_error("--since= must be before --until=.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 270, __func__, "--since= must be before --until=."
) : -abs(_e); })
;
271 return -EINVAL22;
272 }
273
274 return 1;
275}
276
277static int retrieve(const void *data,
278 size_t len,
279 const char *name,
280 char **var) {
281
282 size_t ident;
283 char *v;
284
285 ident = strlen(name) + 1; /* name + "=" */
286
287 if (len
53.1
'len' is >= 'ident'
< ident)
54
Taking false branch
288 return 0;
289
290 if (memcmp(data, name, ident - 1) != 0)
55
Assuming the condition is false
56
Taking false branch
291 return 0;
292
293 if (((const char*) data)[ident - 1] != '=')
57
Assuming the condition is false
58
Taking false branch
294 return 0;
295
296 v = strndup((const char*)data + ident, len - ident);
59
Memory is allocated
297 if (!v)
60
Assuming 'v' is non-null
61
Taking false branch
298 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/coredump/coredumpctl.c"
, 298, __func__)
;
299
300 free(*var);
301 *var = v;
302
303 return 1;
304}
305
306static int print_field(FILE* file, sd_journal *j) {
307 const void *d;
308 size_t l;
309
310 assert(file)do { if ((__builtin_expect(!!(!(file)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("file"), "../src/coredump/coredumpctl.c"
, 310, __PRETTY_FUNCTION__); } while (0)
;
311 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/coredump/coredumpctl.c", 311
, __PRETTY_FUNCTION__); } while (0)
;
312
313 assert(arg_field)do { if ((__builtin_expect(!!(!(arg_field)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("arg_field"), "../src/coredump/coredumpctl.c"
, 313, __PRETTY_FUNCTION__); } while (0)
;
314
315 /* A (user-specified) field may appear more than once for a given entry.
316 * We will print all of the occurences.
317 * This is different below for fields that systemd-coredump uses,
318 * because they cannot meaningfully appear more than once.
319 */
320 SD_JOURNAL_FOREACH_DATA(j, d, l)for (sd_journal_restart_data(j); sd_journal_enumerate_data((j
), &(d), &(l)) > 0; )
{
321 _cleanup_free___attribute__((cleanup(freep))) char *value = NULL((void*)0);
322 int r;
323
324 r = retrieve(d, l, arg_field, &value);
325 if (r < 0)
326 return r;
327 if (r > 0)
328 fprintf(file, "%s\n", value);
329 }
330
331 return 0;
332}
333
334#define RETRIEVE(d, l, name, arg){ int _r = retrieve(d, l, name, &arg); if (_r < 0) return
_r; if (_r > 0) continue; }
\
335 { \
336 int _r = retrieve(d, l, name, &arg); \
337 if (_r < 0) \
338 return _r; \
339 if (_r > 0) \
340 continue; \
341 }
342
343static int print_list(FILE* file, sd_journal *j, int had_legend) {
344 _cleanup_free___attribute__((cleanup(freep))) char
345 *mid = NULL((void*)0), *pid = NULL((void*)0), *uid = NULL((void*)0), *gid = NULL((void*)0),
346 *sgnl = NULL((void*)0), *exe = NULL((void*)0), *comm = NULL((void*)0), *cmdline = NULL((void*)0),
347 *filename = NULL((void*)0), *truncated = NULL((void*)0), *coredump = NULL((void*)0);
348 const void *d;
349 size_t l;
350 usec_t t;
351 char buf[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)];
352 int r;
353 const char *present;
354 bool_Bool normal_coredump;
355
356 assert(file)do { if ((__builtin_expect(!!(!(file)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("file"), "../src/coredump/coredumpctl.c"
, 356, __PRETTY_FUNCTION__); } while (0)
;
357 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/coredump/coredumpctl.c", 357
, __PRETTY_FUNCTION__); } while (0)
;
358
359 SD_JOURNAL_FOREACH_DATA(j, d, l)for (sd_journal_restart_data(j); sd_journal_enumerate_data((j
), &(d), &(l)) > 0; )
{
360 RETRIEVE(d, l, "MESSAGE_ID", mid){ int _r = retrieve(d, l, "MESSAGE_ID", &mid); if (_r <
0) return _r; if (_r > 0) continue; }
;
361 RETRIEVE(d, l, "COREDUMP_PID", pid){ int _r = retrieve(d, l, "COREDUMP_PID", &pid); if (_r <
0) return _r; if (_r > 0) continue; }
;
362 RETRIEVE(d, l, "COREDUMP_UID", uid){ int _r = retrieve(d, l, "COREDUMP_UID", &uid); if (_r <
0) return _r; if (_r > 0) continue; }
;
363 RETRIEVE(d, l, "COREDUMP_GID", gid){ int _r = retrieve(d, l, "COREDUMP_GID", &gid); if (_r <
0) return _r; if (_r > 0) continue; }
;
364 RETRIEVE(d, l, "COREDUMP_SIGNAL", sgnl){ int _r = retrieve(d, l, "COREDUMP_SIGNAL", &sgnl); if (
_r < 0) return _r; if (_r > 0) continue; }
;
365 RETRIEVE(d, l, "COREDUMP_EXE", exe){ int _r = retrieve(d, l, "COREDUMP_EXE", &exe); if (_r <
0) return _r; if (_r > 0) continue; }
;
366 RETRIEVE(d, l, "COREDUMP_COMM", comm){ int _r = retrieve(d, l, "COREDUMP_COMM", &comm); if (_r
< 0) return _r; if (_r > 0) continue; }
;
367 RETRIEVE(d, l, "COREDUMP_CMDLINE", cmdline){ int _r = retrieve(d, l, "COREDUMP_CMDLINE", &cmdline); if
(_r < 0) return _r; if (_r > 0) continue; }
;
368 RETRIEVE(d, l, "COREDUMP_FILENAME", filename){ int _r = retrieve(d, l, "COREDUMP_FILENAME", &filename)
; if (_r < 0) return _r; if (_r > 0) continue; }
;
369 RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated){ int _r = retrieve(d, l, "COREDUMP_TRUNCATED", &truncated
); if (_r < 0) return _r; if (_r > 0) continue; }
;
370 RETRIEVE(d, l, "COREDUMP", coredump){ int _r = retrieve(d, l, "COREDUMP", &coredump); if (_r <
0) return _r; if (_r > 0) continue; }
;
371 }
372
373 if (!pid && !uid && !gid && !sgnl && !exe && !comm && !cmdline && !filename) {
374 log_warning("Empty coredump log entry")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 374, __func__, "Empty coredump log entry"
) : -abs(_e); })
;
375 return -EINVAL22;
376 }
377
378 r = sd_journal_get_realtime_usec(j, &t);
379 if (r < 0)
380 return log_error_errno(r, "Failed to get realtime timestamp: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 380, __func__, "Failed to get realtime timestamp: %m"
) : -abs(_e); })
;
381
382 format_timestamp(buf, sizeof(buf), t);
383
384 if (!had_legend && !arg_no_legend)
385 fprintf(file, "%-*s %*s %*s %*s %*s %-*s %s\n",
386 FORMAT_TIMESTAMP_WIDTH28, "TIME",
387 6, "PID",
388 5, "UID",
389 5, "GID",
390 3, "SIG",
391 9, "COREFILE",
392 "EXE");
393
394 normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR"fc" "2e" "22" "bc" "6e" "e6" "47" "b6" "b9" "07" "29" "ab" "34"
"a2" "50" "b1"
);
395
396 if (filename)
397 if (access(filename, R_OK4) == 0)
398 present = "present";
399 else if (errno(*__errno_location ()) == ENOENT2)
400 present = "missing";
401 else
402 present = "error";
403 else if (coredump)
404 present = "journal";
405 else if (normal_coredump)
406 present = "none";
407 else
408 present = "-";
409
410 if (STR_IN_SET(present, "present", "journal")(!!strv_find((((char**) ((const char*[]) { "present", "journal"
, ((void*)0) }))), (present)))
&& truncated && parse_boolean(truncated) > 0)
411 present = "truncated";
412
413 fprintf(file, "%-*s %*s %*s %*s %*s %-*s %s\n",
414 FORMAT_TIMESTAMP_WIDTH28, buf,
415 6, strna(pid),
416 5, strna(uid),
417 5, strna(gid),
418 3, normal_coredump ? strna(sgnl) : "-",
419 9, present,
420 strna(exe ?: (comm ?: cmdline)));
421
422 return 0;
423}
424
425static int print_info(FILE *file, sd_journal *j, bool_Bool need_space) {
426 _cleanup_free___attribute__((cleanup(freep))) char
427 *mid = NULL((void*)0), *pid = NULL((void*)0), *uid = NULL((void*)0), *gid = NULL((void*)0),
428 *sgnl = NULL((void*)0), *exe = NULL((void*)0), *comm = NULL((void*)0), *cmdline = NULL((void*)0),
429 *unit = NULL((void*)0), *user_unit = NULL((void*)0), *session = NULL((void*)0),
430 *boot_id = NULL((void*)0), *machine_id = NULL((void*)0), *hostname = NULL((void*)0),
431 *slice = NULL((void*)0), *cgroup = NULL((void*)0), *owner_uid = NULL((void*)0),
432 *message = NULL((void*)0), *timestamp = NULL((void*)0), *filename = NULL((void*)0),
433 *truncated = NULL((void*)0), *coredump = NULL((void*)0);
434 const void *d;
435 size_t l;
436 bool_Bool normal_coredump;
437 int r;
438
439 assert(file)do { if ((__builtin_expect(!!(!(file)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("file"), "../src/coredump/coredumpctl.c"
, 439, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'file' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
440 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/coredump/coredumpctl.c", 440
, __PRETTY_FUNCTION__); } while (0)
;
4
Assuming 'j' is non-null
5
Taking false branch
6
Loop condition is false. Exiting loop
441
442 SD_JOURNAL_FOREACH_DATA(j, d, l)for (sd_journal_restart_data(j); sd_journal_enumerate_data((j
), &(d), &(l)) > 0; )
{
7
Assuming the condition is true
8
Loop condition is true. Entering loop body
66
Assuming the condition is true
67
Loop condition is true. Entering loop body
443 RETRIEVE(d, l, "MESSAGE_ID", mid){ int _r = retrieve(d, l, "MESSAGE_ID", &mid); if (_r <
0) return _r; if (_r > 0) continue; }
;
9
Assuming '_r' is >= 0
10
Taking false branch
11
Assuming '_r' is <= 0
12
Taking false branch
68
Assuming '_r' is < 0
69
Taking true branch
70
Potential leak of memory pointed to by 'filename'
444 RETRIEVE(d, l, "COREDUMP_PID", pid){ int _r = retrieve(d, l, "COREDUMP_PID", &pid); if (_r <
0) return _r; if (_r > 0) continue; }
;
13
Taking false branch
14
Taking false branch
445 RETRIEVE(d, l, "COREDUMP_UID", uid){ int _r = retrieve(d, l, "COREDUMP_UID", &uid); if (_r <
0) return _r; if (_r > 0) continue; }
;
15
Taking false branch
16
Taking false branch
446 RETRIEVE(d, l, "COREDUMP_GID", gid){ int _r = retrieve(d, l, "COREDUMP_GID", &gid); if (_r <
0) return _r; if (_r > 0) continue; }
;
17
Taking false branch
18
Taking false branch
447 RETRIEVE(d, l, "COREDUMP_SIGNAL", sgnl){ int _r = retrieve(d, l, "COREDUMP_SIGNAL", &sgnl); if (
_r < 0) return _r; if (_r > 0) continue; }
;
19
Assuming '_r' is >= 0
20
Taking false branch
21
Assuming '_r' is <= 0
22
Taking false branch
448 RETRIEVE(d, l, "COREDUMP_EXE", exe){ int _r = retrieve(d, l, "COREDUMP_EXE", &exe); if (_r <
0) return _r; if (_r > 0) continue; }
;
23
Assuming '_r' is >= 0
24
Taking false branch
25
Assuming '_r' is <= 0
26
Taking false branch
449 RETRIEVE(d, l, "COREDUMP_COMM", comm){ int _r = retrieve(d, l, "COREDUMP_COMM", &comm); if (_r
< 0) return _r; if (_r > 0) continue; }
;
27
Assuming '_r' is >= 0
28
Taking false branch
29
Assuming '_r' is <= 0
30
Taking false branch
450 RETRIEVE(d, l, "COREDUMP_CMDLINE", cmdline){ int _r = retrieve(d, l, "COREDUMP_CMDLINE", &cmdline); if
(_r < 0) return _r; if (_r > 0) continue; }
;
31
Assuming '_r' is >= 0
32
Taking false branch
33
Assuming '_r' is <= 0
34
Taking false branch
451 RETRIEVE(d, l, "COREDUMP_UNIT", unit){ int _r = retrieve(d, l, "COREDUMP_UNIT", &unit); if (_r
< 0) return _r; if (_r > 0) continue; }
;
35
Taking false branch
36
Taking false branch
452 RETRIEVE(d, l, "COREDUMP_USER_UNIT", user_unit){ int _r = retrieve(d, l, "COREDUMP_USER_UNIT", &user_unit
); if (_r < 0) return _r; if (_r > 0) continue; }
;
37
Taking false branch
38
Taking false branch
453 RETRIEVE(d, l, "COREDUMP_SESSION", session){ int _r = retrieve(d, l, "COREDUMP_SESSION", &session); if
(_r < 0) return _r; if (_r > 0) continue; }
;
39
Taking false branch
40
Taking false branch
454 RETRIEVE(d, l, "COREDUMP_OWNER_UID", owner_uid){ int _r = retrieve(d, l, "COREDUMP_OWNER_UID", &owner_uid
); if (_r < 0) return _r; if (_r > 0) continue; }
;
41
Taking false branch
42
Taking false branch
455 RETRIEVE(d, l, "COREDUMP_SLICE", slice){ int _r = retrieve(d, l, "COREDUMP_SLICE", &slice); if (
_r < 0) return _r; if (_r > 0) continue; }
;
43
Assuming '_r' is >= 0
44
Taking false branch
45
Assuming '_r' is <= 0
46
Taking false branch
456 RETRIEVE(d, l, "COREDUMP_CGROUP", cgroup){ int _r = retrieve(d, l, "COREDUMP_CGROUP", &cgroup); if
(_r < 0) return _r; if (_r > 0) continue; }
;
47
Taking false branch
48
Taking false branch
457 RETRIEVE(d, l, "COREDUMP_TIMESTAMP", timestamp){ int _r = retrieve(d, l, "COREDUMP_TIMESTAMP", &timestamp
); if (_r < 0) return _r; if (_r > 0) continue; }
;
49
Assuming '_r' is >= 0
50
Taking false branch
51
Assuming '_r' is <= 0
52
Taking false branch
458 RETRIEVE(d, l, "COREDUMP_FILENAME", filename){ int _r = retrieve(d, l, "COREDUMP_FILENAME", &filename)
; if (_r < 0) return _r; if (_r > 0) continue; }
;
53
Calling 'retrieve'
62
Returned allocated memory via 4th parameter
63
Taking false branch
64
Taking true branch
65
Execution continues on line 442
459 RETRIEVE(d, l, "COREDUMP_TRUNCATED", truncated){ int _r = retrieve(d, l, "COREDUMP_TRUNCATED", &truncated
); if (_r < 0) return _r; if (_r > 0) continue; }
;
460 RETRIEVE(d, l, "COREDUMP", coredump){ int _r = retrieve(d, l, "COREDUMP", &coredump); if (_r <
0) return _r; if (_r > 0) continue; }
;
461 RETRIEVE(d, l, "_BOOT_ID", boot_id){ int _r = retrieve(d, l, "_BOOT_ID", &boot_id); if (_r <
0) return _r; if (_r > 0) continue; }
;
462 RETRIEVE(d, l, "_MACHINE_ID", machine_id){ int _r = retrieve(d, l, "_MACHINE_ID", &machine_id); if
(_r < 0) return _r; if (_r > 0) continue; }
;
463 RETRIEVE(d, l, "_HOSTNAME", hostname){ int _r = retrieve(d, l, "_HOSTNAME", &hostname); if (_r
< 0) return _r; if (_r > 0) continue; }
;
464 RETRIEVE(d, l, "MESSAGE", message){ int _r = retrieve(d, l, "MESSAGE", &message); if (_r <
0) return _r; if (_r > 0) continue; }
;
465 }
466
467 if (need_space)
468 fputs("\n", file);
469
470 normal_coredump = streq_ptr(mid, SD_MESSAGE_COREDUMP_STR"fc" "2e" "22" "bc" "6e" "e6" "47" "b6" "b9" "07" "29" "ab" "34"
"a2" "50" "b1"
);
471
472 if (comm)
473 fprintf(file,
474 " PID: %s%s%s (%s)\n",
475 ansi_highlight(), strna(pid), ansi_normal(), comm);
476 else
477 fprintf(file,
478 " PID: %s%s%s\n",
479 ansi_highlight(), strna(pid), ansi_normal());
480
481 if (uid) {
482 uid_t n;
483
484 if (parse_uid(uid, &n) >= 0) {
485 _cleanup_free___attribute__((cleanup(freep))) char *u = NULL((void*)0);
486
487 u = uid_to_name(n);
488 fprintf(file,
489 " UID: %s (%s)\n",
490 uid, u);
491 } else {
492 fprintf(file,
493 " UID: %s\n",
494 uid);
495 }
496 }
497
498 if (gid) {
499 gid_t n;
500
501 if (parse_gid(gid, &n) >= 0) {
502 _cleanup_free___attribute__((cleanup(freep))) char *g = NULL((void*)0);
503
504 g = gid_to_name(n);
505 fprintf(file,
506 " GID: %s (%s)\n",
507 gid, g);
508 } else {
509 fprintf(file,
510 " GID: %s\n",
511 gid);
512 }
513 }
514
515 if (sgnl) {
516 int sig;
517 const char *name = normal_coredump ? "Signal" : "Reason";
518
519 if (normal_coredump && safe_atoi(sgnl, &sig) >= 0)
520 fprintf(file, " %s: %s (%s)\n", name, sgnl, signal_to_string(sig));
521 else
522 fprintf(file, " %s: %s\n", name, sgnl);
523 }
524
525 if (timestamp) {
526 usec_t u;
527
528 r = safe_atou64(timestamp, &u);
529 if (r >= 0) {
530 char absolute[FORMAT_TIMESTAMP_MAX(3+1+10+1+8+1+6+1+6+1)], relative[FORMAT_TIMESPAN_MAX64];
531
532 fprintf(file,
533 " Timestamp: %s (%s)\n",
534 format_timestamp(absolute, sizeof(absolute), u),
535 format_timestamp_relative(relative, sizeof(relative), u));
536
537 } else
538 fprintf(file, " Timestamp: %s\n", timestamp);
539 }
540
541 if (cmdline)
542 fprintf(file, " Command Line: %s\n", cmdline);
543 if (exe)
544 fprintf(file, " Executable: %s%s%s\n", ansi_highlight(), exe, ansi_normal());
545 if (cgroup)
546 fprintf(file, " Control Group: %s\n", cgroup);
547 if (unit)
548 fprintf(file, " Unit: %s\n", unit);
549 if (user_unit)
550 fprintf(file, " User Unit: %s\n", user_unit);
551 if (slice)
552 fprintf(file, " Slice: %s\n", slice);
553 if (session)
554 fprintf(file, " Session: %s\n", session);
555 if (owner_uid) {
556 uid_t n;
557
558 if (parse_uid(owner_uid, &n) >= 0) {
559 _cleanup_free___attribute__((cleanup(freep))) char *u = NULL((void*)0);
560
561 u = uid_to_name(n);
562 fprintf(file,
563 " Owner UID: %s (%s)\n",
564 owner_uid, u);
565 } else {
566 fprintf(file,
567 " Owner UID: %s\n",
568 owner_uid);
569 }
570 }
571 if (boot_id)
572 fprintf(file, " Boot ID: %s\n", boot_id);
573 if (machine_id)
574 fprintf(file, " Machine ID: %s\n", machine_id);
575 if (hostname)
576 fprintf(file, " Hostname: %s\n", hostname);
577
578 if (filename) {
579 bool_Bool inacc, trunc;
580
581 inacc = access(filename, R_OK4) < 0;
582 trunc = truncated && parse_boolean(truncated) > 0;
583
584 if (inacc || trunc)
585 fprintf(file, " Storage: %s%s (%s%s%s)%s\n",
586 ansi_highlight_red(),
587 filename,
588 inacc ? "inaccessible" : "",
589 inacc && trunc ? ", " : "",
590 trunc ? "truncated" : "",
591 ansi_normal());
592 else
593 fprintf(file, " Storage: %s\n", filename);
594 }
595
596 else if (coredump)
597 fprintf(file, " Storage: journal\n");
598 else
599 fprintf(file, " Storage: none\n");
600
601 if (message) {
602 _cleanup_free___attribute__((cleanup(freep))) char *m = NULL((void*)0);
603
604 m = strreplace(message, "\n", "\n ");
605
606 fprintf(file, " Message: %s\n", strstrip(m ?: message));
607 }
608
609 return 0;
610}
611
612static int focus(sd_journal *j) {
613 int r;
614
615 r = sd_journal_seek_tail(j);
616 if (r == 0)
617 r = sd_journal_previous(j);
618 if (r < 0)
619 return log_error_errno(r, "Failed to search journal: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 619, __func__, "Failed to search journal: %m"
) : -abs(_e); })
;
620 if (r == 0) {
621 log_error("No match found.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 621, __func__, "No match found."
) : -abs(_e); })
;
622 return -ESRCH3;
623 }
624 return r;
625}
626
627static int print_entry(sd_journal *j, unsigned n_found, bool_Bool verb_is_info) {
628 assert(j)do { if ((__builtin_expect(!!(!(j)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("j"), "../src/coredump/coredumpctl.c", 628
, __PRETTY_FUNCTION__); } while (0)
;
629
630 if (verb_is_info)
631 return print_info(stdoutstdout, j, n_found);
632 else if (arg_field)
633 return print_field(stdoutstdout, j);
634 else
635 return print_list(stdoutstdout, j, n_found);
636}
637
638static int dump_list(int argc, char **argv, void *userdata) {
639 _cleanup_(sd_journal_closep)__attribute__((cleanup(sd_journal_closep))) sd_journal *j = NULL((void*)0);
640 unsigned n_found = 0;
641 bool_Bool verb_is_info;
642 int r;
643
644 verb_is_info = (argc >= 1 && streq(argv[0], "info")(strcmp((argv[0]),("info")) == 0));
645
646 r = acquire_journal(&j, argv + 1);
647 if (r < 0)
648 return r;
649
650 (void) pager_open(arg_no_pager, false0);
651
652 /* The coredumps are likely to compressed, and for just
653 * listing them we don't need to decompress them, so let's
654 * pick a fairly low data threshold here */
655 sd_journal_set_data_threshold(j, 4096);
656
657 if (arg_one) {
658 r = focus(j);
659 if (r < 0)
660 return r;
661
662 return print_entry(j, 0, verb_is_info);
663 } else {
664 if (arg_since != USEC_INFINITY((usec_t) -1) && !arg_reverse)
665 r = sd_journal_seek_realtime_usec(j, arg_since);
666 else if (arg_until != USEC_INFINITY((usec_t) -1) && arg_reverse)
667 r = sd_journal_seek_realtime_usec(j, arg_until);
668 else if (arg_reverse)
669 r = sd_journal_seek_tail(j);
670 else
671 r = sd_journal_seek_head(j);
672 if (r < 0)
673 return log_error_errno(r, "Failed to seek to date: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 673, __func__, "Failed to seek to date: %m"
) : -abs(_e); })
;
674
675 for (;;) {
676 if (!arg_reverse)
677 r = sd_journal_next(j);
678 else
679 r = sd_journal_previous(j);
680
681 if (r < 0)
682 return log_error_errno(r, "Failed to iterate through journal: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 682, __func__, "Failed to iterate through journal: %m"
) : -abs(_e); })
;
683
684 if (r == 0)
685 break;
686
687 if (arg_until != USEC_INFINITY((usec_t) -1) && !arg_reverse) {
688 usec_t usec;
689
690 r = sd_journal_get_realtime_usec(j, &usec);
691 if (r < 0)
692 return log_error_errno(r, "Failed to determine timestamp: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 692, __func__, "Failed to determine timestamp: %m"
) : -abs(_e); })
;
693 if (usec > arg_until)
694 continue;
695 }
696
697 if (arg_since != USEC_INFINITY((usec_t) -1) && arg_reverse) {
698 usec_t usec;
699
700 r = sd_journal_get_realtime_usec(j, &usec);
701 if (r < 0)
702 return log_error_errno(r, "Failed to determine timestamp: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 702, __func__, "Failed to determine timestamp: %m"
) : -abs(_e); })
;
703 if (usec < arg_since)
704 continue;
705 }
706
707 r = print_entry(j, n_found++, verb_is_info);
708 if (r < 0)
709 return r;
710 }
711
712 if (!arg_field && n_found <= 0) {
713 if (!arg_quiet)
714 log_notice("No coredumps found.")({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 714, __func__, "No coredumps found."
) : -abs(_e); })
;
715 return -ESRCH3;
716 }
717 }
718
719 return 0;
720}
721
722static int save_core(sd_journal *j, FILE *file, char **path, bool_Bool *unlink_temp) {
723 const char *data;
724 _cleanup_free___attribute__((cleanup(freep))) char *filename = NULL((void*)0);
725 size_t len;
726 int r, fd;
727 _cleanup_close___attribute__((cleanup(closep))) int fdt = -1;
728 char *temp = NULL((void*)0);
729
730 assert(!(file && path))do { if ((__builtin_expect(!!(!(!(file && path))),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("!(file && path)"
), "../src/coredump/coredumpctl.c", 730, __PRETTY_FUNCTION__)
; } while (0)
; /* At most one can be specified */
731 assert(!!path == !!unlink_temp)do { if ((__builtin_expect(!!(!(!!path == !!unlink_temp)),0))
) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("!!path == !!unlink_temp"
), "../src/coredump/coredumpctl.c", 731, __PRETTY_FUNCTION__)
; } while (0)
; /* Those must be specified together */
732
733 /* Look for a coredump on disk first. */
734 r = sd_journal_get_data(j, "COREDUMP_FILENAME", (const void**) &data, &len);
735 if (r == 0)
736 retrieve(data, len, "COREDUMP_FILENAME", &filename);
737 else {
738 if (r != -ENOENT2)
739 return log_error_errno(r, "Failed to retrieve COREDUMP_FILENAME field: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 739, __func__, "Failed to retrieve COREDUMP_FILENAME field: %m"
) : -abs(_e); })
;
740 /* Check that we can have a COREDUMP field. We still haven't set a high
741 * data threshold, so we'll get a few kilobytes at most.
742 */
743
744 r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
745 if (r == -ENOENT2)
746 return log_error_errno(r, "Coredump entry has no core attached (neither internally in the journal nor externally on disk).")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 746, __func__, "Coredump entry has no core attached (neither internally in the journal nor externally on disk)."
) : -abs(_e); })
;
747 if (r < 0)
748 return log_error_errno(r, "Failed to retrieve COREDUMP field: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 748, __func__, "Failed to retrieve COREDUMP field: %m"
) : -abs(_e); })
;
749 }
750
751 if (filename) {
752 if (access(filename, R_OK4) < 0)
753 return log_error_errno(errno, "File \"%s\" is not readable: %m", filename)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/coredump/coredumpctl.c", 753, __func__
, "File \"%s\" is not readable: %m", filename) : -abs(_e); })
;
754
755 if (path && !endswith(filename, ".xz") && !endswith(filename, ".lz4")) {
756 *path = TAKE_PTR(filename)({ typeof(filename) _ptr_ = (filename); (filename) = ((void*)
0); _ptr_; })
;
757
758 return 0;
759 }
760 }
761
762 if (path) {
763 const char *vt;
764
765 /* Create a temporary file to write the uncompressed core to. */
766
767 r = var_tmp_dir(&vt);
768 if (r < 0)
769 return log_error_errno(r, "Failed to acquire temporary directory path: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 769, __func__, "Failed to acquire temporary directory path: %m"
) : -abs(_e); })
;
770
771 temp = strjoin(vt, "/coredump-XXXXXX")strjoin_real((vt), "/coredump-XXXXXX", ((void*)0));
772 if (!temp)
773 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/coredump/coredumpctl.c"
, 773, __func__)
;
774
775 fdt = mkostemp_safe(temp);
776 if (fdt < 0)
777 return log_error_errno(fdt, "Failed to create temporary file: %m")({ int _level = ((3)), _e = ((fdt)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 777, __func__, "Failed to create temporary file: %m"
) : -abs(_e); })
;
778 log_debug("Created temporary file %s", temp)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 778, __func__, "Created temporary file %s"
, temp) : -abs(_e); })
;
779
780 fd = fdt;
781 } else {
782 /* If neither path or file are specified, we will write to stdout. Let's now check
783 * if stdout is connected to a tty. We checked that the file exists, or that the
784 * core might be stored in the journal. In this second case, if we found the entry,
785 * in all likelyhood we will be able to access the COREDUMP= field. In either case,
786 * we stop before doing any "real" work, i.e. before starting decompression or
787 * reading from the file or creating temporary files.
788 */
789 if (!file) {
790 if (on_tty())
791 return log_error_errno(ENOTTY, "Refusing to dump core to tty"({ int _level = ((3)), _e = ((25)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 792, __func__, "Refusing to dump core to tty"
" (use shell redirection or specify --output).") : -abs(_e);
})
792 " (use shell redirection or specify --output).")({ int _level = ((3)), _e = ((25)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 792, __func__, "Refusing to dump core to tty"
" (use shell redirection or specify --output).") : -abs(_e);
})
;
793 file = stdoutstdout;
794 }
795
796 fd = fileno(file);
797 }
798
799 if (filename) {
800#if HAVE_XZ1 || HAVE_LZ41
801 _cleanup_close___attribute__((cleanup(closep))) int fdf;
802
803 fdf = open(filename, O_RDONLY00 | O_CLOEXEC02000000);
804 if (fdf < 0) {
805 r = log_error_errno(errno, "Failed to open %s: %m", filename)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/coredump/coredumpctl.c", 805, __func__
, "Failed to open %s: %m", filename) : -abs(_e); })
;
806 goto error;
807 }
808
809 r = decompress_stream(filename, fdf, fd, -1);
810 if (r < 0) {
811 log_error_errno(r, "Failed to decompress %s: %m", filename)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 811, __func__, "Failed to decompress %s: %m"
, filename) : -abs(_e); })
;
812 goto error;
813 }
814#else
815 log_error("Cannot decompress file. Compiled without compression support.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 815, __func__, "Cannot decompress file. Compiled without compression support."
) : -abs(_e); })
;
816 r = -EOPNOTSUPP95;
817 goto error;
818#endif
819 } else {
820 ssize_t sz;
821
822 /* We want full data, nothing truncated. */
823 sd_journal_set_data_threshold(j, 0);
824
825 r = sd_journal_get_data(j, "COREDUMP", (const void**) &data, &len);
826 if (r < 0)
827 return log_error_errno(r, "Failed to retrieve COREDUMP field: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 827, __func__, "Failed to retrieve COREDUMP field: %m"
) : -abs(_e); })
;
828
829 assert(len >= 9)do { if ((__builtin_expect(!!(!(len >= 9)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("len >= 9"), "../src/coredump/coredumpctl.c"
, 829, __PRETTY_FUNCTION__); } while (0)
;
830 data += 9;
831 len -= 9;
832
833 sz = write(fd, data, len);
834 if (sz < 0) {
835 r = log_error_errno(errno, "Failed to write output: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/coredump/coredumpctl.c", 835, __func__
, "Failed to write output: %m") : -abs(_e); })
;
836 goto error;
837 }
838 if (sz != (ssize_t) len) {
839 log_error("Short write to output.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 839, __func__, "Short write to output."
) : -abs(_e); })
;
840 r = -EIO5;
841 goto error;
842 }
843 }
844
845 if (temp) {
846 *path = temp;
847 *unlink_temp = true1;
848 }
849 return 0;
850
851error:
852 if (temp) {
853 unlink(temp);
854 log_debug("Removed temporary file %s", temp)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 854, __func__, "Removed temporary file %s"
, temp) : -abs(_e); })
;
855 }
856 return r;
857}
858
859static int dump_core(int argc, char **argv, void *userdata) {
860 _cleanup_(sd_journal_closep)__attribute__((cleanup(sd_journal_closep))) sd_journal *j = NULL((void*)0);
861 int r;
862
863 if (arg_field) {
864 log_error("Option --field/-F only makes sense with list")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 864, __func__, "Option --field/-F only makes sense with list"
) : -abs(_e); })
;
865 return -EINVAL22;
866 }
867
868 r = acquire_journal(&j, argv + 1);
869 if (r < 0)
870 return r;
871
872 r = focus(j);
873 if (r < 0)
874 return r;
875
876 print_info(arg_output ? stdoutstdout : stderrstderr, j, false0);
877
878 r = save_core(j, arg_output, NULL((void*)0), NULL((void*)0));
879 if (r < 0)
880 return r;
881
882 r = sd_journal_previous(j);
883 if (r > 0 && !arg_quiet)
884 log_notice("More than one entry matches, ignoring rest.")({ int _level = (((5))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 884, __func__, "More than one entry matches, ignoring rest."
) : -abs(_e); })
;
885
886 return 0;
887}
888
889static int run_debug(int argc, char **argv, void *userdata) {
890 _cleanup_(sd_journal_closep)__attribute__((cleanup(sd_journal_closep))) sd_journal *j = NULL((void*)0);
891 _cleanup_free___attribute__((cleanup(freep))) char *exe = NULL((void*)0), *path = NULL((void*)0);
892 bool_Bool unlink_path = false0;
893 const char *data, *fork_name;
894 size_t len;
895 pid_t pid;
896 int r;
897
898 if (!arg_debugger) {
899 char *env_debugger;
900
901 env_debugger = getenv("SYSTEMD_DEBUGGER");
902 if (env_debugger)
903 arg_debugger = env_debugger;
904 else
905 arg_debugger = "gdb";
906 }
907
908 if (arg_field) {
909 log_error("Option --field/-F only makes sense with list")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 909, __func__, "Option --field/-F only makes sense with list"
) : -abs(_e); })
;
910 return -EINVAL22;
911 }
912
913 r = acquire_journal(&j, argv + 1);
914 if (r < 0)
915 return r;
916
917 r = focus(j);
918 if (r < 0)
919 return r;
920
921 print_info(stdoutstdout, j, false0);
922 fputs("\n", stdoutstdout);
923
924 r = sd_journal_get_data(j, "COREDUMP_EXE", (const void**) &data, &len);
925 if (r < 0)
926 return log_error_errno(r, "Failed to retrieve COREDUMP_EXE field: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 926, __func__, "Failed to retrieve COREDUMP_EXE field: %m"
) : -abs(_e); })
;
927
928 assert(len > STRLEN("COREDUMP_EXE="))do { if ((__builtin_expect(!!(!(len > (sizeof("""COREDUMP_EXE="
"") - 1))),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("len > STRLEN(\"COREDUMP_EXE=\")"
), "../src/coredump/coredumpctl.c", 928, __PRETTY_FUNCTION__)
; } while (0)
;
929 data += STRLEN("COREDUMP_EXE=")(sizeof("""COREDUMP_EXE=""") - 1);
930 len -= STRLEN("COREDUMP_EXE=")(sizeof("""COREDUMP_EXE=""") - 1);
931
932 exe = strndup(data, len);
933 if (!exe)
934 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/coredump/coredumpctl.c"
, 934, __func__)
;
935
936 if (endswith(exe, " (deleted)")) {
937 log_error("Binary already deleted.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 937, __func__, "Binary already deleted."
) : -abs(_e); })
;
938 return -ENOENT2;
939 }
940
941 if (!path_is_absolute(exe)) {
942 log_error("Binary is not an absolute path.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 942, __func__, "Binary is not an absolute path."
) : -abs(_e); })
;
943 return -ENOENT2;
944 }
945
946 r = save_core(j, NULL((void*)0), &path, &unlink_path);
947 if (r < 0)
948 return r;
949
950 /* Don't interfere with gdb and its handling of SIGINT. */
951 (void) ignore_signals(SIGINT2, -1);
952
953 fork_name = strjoina("(", arg_debugger, ")")({ const char *_appendees_[] = { "(", arg_debugger, ")" }; char
*_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ <
__extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
954
955 r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_LOG, &pid);
956 if (r < 0)
957 goto finish;
958 if (r == 0) {
959 execlp(arg_debugger, arg_debugger, exe, "-c", path, NULL((void*)0));
960 log_open();
961 log_error_errno(errno, "Failed to invoke %s: %m", arg_debugger)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/coredump/coredumpctl.c", 961, __func__
, "Failed to invoke %s: %m", arg_debugger) : -abs(_e); })
;
962 _exit(EXIT_FAILURE1);
963 }
964
965 r = wait_for_terminate_and_check(arg_debugger, pid, WAIT_LOG_ABNORMAL);
966
967finish:
968 (void) default_signals(SIGINT2, -1);
969
970 if (unlink_path) {
971 log_debug("Removed temporary file %s", path)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 971, __func__, "Removed temporary file %s"
, path) : -abs(_e); })
;
972 unlink(path);
973 }
974
975 return r;
976}
977
978static int check_units_active(void) {
979 _cleanup_(sd_bus_unrefp)__attribute__((cleanup(sd_bus_unrefp))) sd_bus *bus = NULL((void*)0);
980 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *m = NULL((void*)0);
981 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
982 _cleanup_(sd_bus_message_unrefp)__attribute__((cleanup(sd_bus_message_unrefp))) sd_bus_message *reply = NULL((void*)0);
983 int c = 0, r;
984 const char *id, *state, *substate;
985
986 if (arg_quiet)
987 return false0;
988
989 r = sd_bus_default_system(&bus);
990 if (r < 0)
991 return log_error_errno(r, "Failed to acquire bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 991, __func__, "Failed to acquire bus: %m"
) : -abs(_e); })
;
992
993 r = sd_bus_message_new_method_call(
994 bus,
995 &m,
996 "org.freedesktop.systemd1",
997 "/org/freedesktop/systemd1",
998 "org.freedesktop.systemd1.Manager",
999 "ListUnitsByPatterns");
1000 if (r < 0)
1001 return bus_log_create_error(r);
1002
1003 r = sd_bus_message_append_strv(m, NULL((void*)0));
1004 if (r < 0)
1005 return bus_log_create_error(r);
1006
1007 r = sd_bus_message_append_strv(m, STRV_MAKE("systemd-coredump@*.service")((char**) ((const char*[]) { "systemd-coredump@*.service", ((
void*)0) }))
);
1008 if (r < 0)
1009 return bus_log_create_error(r);
1010
1011 r = sd_bus_call(bus, m, SHORT_BUS_CALL_TIMEOUT_USEC(3 * ((usec_t) 1000000ULL)), &error, &reply);
1012 if (r < 0)
1013 return log_error_errno(r, "Failed to check if any systemd-coredump@.service units are running: %s",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 1014, __func__, "Failed to check if any systemd-coredump@.service units are running: %s"
, bus_error_message(&error, r)) : -abs(_e); })
1014 bus_error_message(&error, r))({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 1014, __func__, "Failed to check if any systemd-coredump@.service units are running: %s"
, bus_error_message(&error, r)) : -abs(_e); })
;
1015
1016 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
1017 if (r < 0)
1018 return bus_log_parse_error(r);
1019
1020 while ((r = sd_bus_message_read(
1021 reply, "(ssssssouso)",
1022 &id, NULL((void*)0), NULL((void*)0), &state, &substate,
1023 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0))) > 0) {
1024 bool_Bool found = !STR_IN_SET(state, "inactive", "dead", "failed")(!!strv_find((((char**) ((const char*[]) { "inactive", "dead"
, "failed", ((void*)0) }))), (state)))
;
1025 log_debug("Unit %s is %s/%s, %scounting it.", id, state, substate, found ? "" : "not ")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/coredump/coredumpctl.c", 1025, __func__, "Unit %s is %s/%s, %scounting it."
, id, state, substate, found ? "" : "not ") : -abs(_e); })
;
1026 c += found;
1027 }
1028 if (r < 0)
1029 return bus_log_parse_error(r);
1030
1031 r = sd_bus_message_exit_container(reply);
1032 if (r < 0)
1033 return bus_log_parse_error(r);
1034
1035 return c;
1036}
1037
1038static int coredumpctl_main(int argc, char *argv[]) {
1039
1040 static const Verb verbs[] = {
1041 { "list", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), VERB_DEFAULT, dump_list },
1042 { "info", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, dump_list },
1043 { "dump", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, dump_core },
1044 { "debug", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, run_debug },
1045 { "gdb", VERB_ANY((unsigned) -1), VERB_ANY((unsigned) -1), 0, run_debug },
1046 {}
1047 };
1048
1049 return dispatch_verb(argc, argv, verbs, NULL((void*)0));
1050}
1051
1052int main(int argc, char *argv[]) {
1053 int r, units_active;
1054
1055 setlocale(LC_ALL6, "");
1056 log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD);
1057 log_open();
1058
1059 r = parse_argv(argc, argv);
1060 if (r <= 0)
1061 goto end;
1062
1063 sigbus_install();
1064
1065 units_active = check_units_active(); /* error is treated the same as 0 */
1066
1067 r = coredumpctl_main(argc, argv);
1068
1069 if (units_active > 0)
1070 printf("%s-- Notice: %d systemd-coredump@.service %s, output may be incomplete.%s\n",
1071 ansi_highlight_red(),
1072 units_active, units_active == 1 ? "unit is running" : "units are running",
1073 ansi_normal());
1074end:
1075 pager_close();
1076
1077 safe_fclose(arg_output);
1078
1079 return r >= 0 ? r : EXIT_FAILURE1;
1080}