Skip to content

Commit 6740ec4

Browse files
authored
Merge pull request systemd#4225 from keszybz/coredump
coredump: remove Storage=both support, various fixes for sd-coredump and coredumpctl
2 parents b9fe94c + 73a9916 commit 6740ec4

File tree

6 files changed

+264
-190
lines changed

6 files changed

+264
-190
lines changed

TODO

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,7 @@ Features:
670670

671671
* coredump:
672672
- save coredump in Windows/Mozilla minidump format
673+
- when truncating coredumps, also log the full size that the process had, and make a metadata field so we can report truncated coredumps
673674

674675
* support crash reporting operation modes (https://live.gnome.org/GnomeOS/Design/Whiteboards/ProblemReporting)
675676

catalog/systemd.catalog.in

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,17 @@ Process @COREDUMP_PID@ (@COREDUMP_COMM@) crashed and dumped core.
8888
This usually indicates a programming error in the crashing program and
8989
should be reported to its vendor as a bug.
9090

91+
-- 5aadd8e954dc4b1a8c954d63fd9e1137
92+
Subject: Core file was truncated to @SIZE_LIMIT@ bytes.
93+
Defined-By: systemd
94+
Support: %SUPPORT_URL%
95+
Documentation: man:coredump.conf(5)
96+
97+
The process had more memory mapped than the configured maximum for processing
98+
and storage by systemd-coredump(8). Only the first @SIZE_LIMIT@ bytes were
99+
saved. This core might still be usable, but various tools like gdb(1) will warn
100+
about the file being truncated.
101+
91102
-- fc2e22bc6ee647b6b90729ab34a250b1 de
92103
Subject: Speicherabbild für Prozess @COREDUMP_PID@ (@COREDUMP_COMM) generiert
93104
Defined-By: systemd

man/coredump.conf.xml

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,13 @@
8383
<varlistentry>
8484
<term><varname>Storage=</varname></term>
8585

86-
<listitem><para>Controls where to store cores. One of
87-
<literal>none</literal>, <literal>external</literal>,
88-
<literal>journal</literal>, and <literal>both</literal>. When
89-
<literal>none</literal>, the core dumps will be logged but not
90-
stored permanently. When <literal>external</literal> (the
91-
default), cores will be stored in <filename>/var/lib/systemd/coredump</filename>.
92-
When <literal>journal</literal>, cores will be stored in
93-
the journal and rotated following normal journal
94-
rotation patterns. When <literal>both</literal>, cores
95-
will be stored in both locations.</para>
86+
<listitem><para>Controls where to store cores. One of <literal>none</literal>,
87+
<literal>external</literal>, and <literal>journal</literal>. When
88+
<literal>none</literal>, the core dumps will be logged (included the traceback if
89+
possible), but not stored permanently. When <literal>external</literal> (the
90+
default), cores will be stored in <filename>/var/lib/systemd/coredump/</filename>.
91+
When <literal>journal</literal>, cores will be stored in the journal and rotated
92+
following normal journal rotation patterns.</para>
9693

9794
<para>When cores are stored in the journal, they might be
9895
compressed following journal compression settings, see

src/coredump/coredump.c

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
#include <elfutils/libdwfl.h>
2929
#endif
3030

31+
#include "sd-daemon.h"
3132
#include "sd-journal.h"
3233
#include "sd-login.h"
33-
#include "sd-daemon.h"
34+
#include "sd-messages.h"
3435

3536
#include "acl-util.h"
3637
#include "alloc-util.h"
@@ -93,7 +94,6 @@ typedef enum CoredumpStorage {
9394
COREDUMP_STORAGE_NONE,
9495
COREDUMP_STORAGE_EXTERNAL,
9596
COREDUMP_STORAGE_JOURNAL,
96-
COREDUMP_STORAGE_BOTH,
9797
_COREDUMP_STORAGE_MAX,
9898
_COREDUMP_STORAGE_INVALID = -1
9999
} CoredumpStorage;
@@ -102,7 +102,6 @@ static const char* const coredump_storage_table[_COREDUMP_STORAGE_MAX] = {
102102
[COREDUMP_STORAGE_NONE] = "none",
103103
[COREDUMP_STORAGE_EXTERNAL] = "external",
104104
[COREDUMP_STORAGE_JOURNAL] = "journal",
105-
[COREDUMP_STORAGE_BOTH] = "both",
106105
};
107106

108107
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(coredump_storage, CoredumpStorage);
@@ -135,6 +134,10 @@ static int parse_config(void) {
135134
false, NULL);
136135
}
137136

137+
static inline uint64_t storage_size_max(void) {
138+
return arg_storage == COREDUMP_STORAGE_EXTERNAL ? arg_external_size_max : arg_journal_size_max;
139+
}
140+
138141
static int fix_acl(int fd, uid_t uid) {
139142

140143
#ifdef HAVE_ACL
@@ -247,7 +250,7 @@ static int maybe_remove_external_coredump(const char *filename, uint64_t size) {
247250

248251
/* Returns 1 if might remove, 0 if will not remove, < 0 on error. */
249252

250-
if (IN_SET(arg_storage, COREDUMP_STORAGE_EXTERNAL, COREDUMP_STORAGE_BOTH) &&
253+
if (arg_storage == COREDUMP_STORAGE_EXTERNAL &&
251254
size <= arg_external_size_max)
252255
return 0;
253256

@@ -331,12 +334,13 @@ static int save_external_coredump(
331334
/* Is coredumping disabled? Then don't bother saving/processing the coredump.
332335
* Anything below PAGE_SIZE cannot give a readable coredump (the kernel uses
333336
* ELF_EXEC_PAGESIZE which is not easily accessible, but is usually the same as PAGE_SIZE. */
334-
log_info("Core dumping has been disabled for process %s (%s).", context[CONTEXT_PID], context[CONTEXT_COMM]);
337+
log_info("Resource limits disable core dumping for process %s (%s).",
338+
context[CONTEXT_PID], context[CONTEXT_COMM]);
335339
return -EBADSLT;
336340
}
337341

338342
/* Never store more than the process configured, or than we actually shall keep or process */
339-
max_size = MIN(rlimit, MAX(arg_process_size_max, arg_external_size_max));
343+
max_size = MIN(rlimit, MAX(arg_process_size_max, storage_size_max()));
340344

341345
r = make_filename(context, &fn);
342346
if (r < 0)
@@ -349,19 +353,18 @@ static int save_external_coredump(
349353
return log_error_errno(fd, "Failed to create temporary file for coredump %s: %m", fn);
350354

351355
r = copy_bytes(input_fd, fd, max_size, false);
352-
if (r == -EFBIG) {
353-
log_error("Coredump of %s (%s) is larger than configured processing limit, refusing.", context[CONTEXT_PID], context[CONTEXT_COMM]);
354-
goto fail;
355-
} else if (IN_SET(r, -EDQUOT, -ENOSPC)) {
356-
log_error("Not enough disk space for coredump of %s (%s), refusing.", context[CONTEXT_PID], context[CONTEXT_COMM]);
357-
goto fail;
358-
} else if (r < 0) {
359-
log_error_errno(r, "Failed to dump coredump to file: %m");
356+
if (r < 0) {
357+
log_error_errno(r, "Cannot store coredump of %s (%s): %m", context[CONTEXT_PID], context[CONTEXT_COMM]);
360358
goto fail;
361-
}
359+
} else if (r == 1)
360+
log_struct(LOG_INFO,
361+
LOG_MESSAGE("Core file was truncated to %zu bytes.", max_size),
362+
"SIZE_LIMIT=%zu", max_size,
363+
LOG_MESSAGE_ID(SD_MESSAGE_TRUNCATED_CORE),
364+
NULL);
362365

363366
if (fstat(fd, &st) < 0) {
364-
log_error_errno(errno, "Failed to fstat coredump %s: %m", coredump_tmpfile_name(tmp));
367+
log_error_errno(errno, "Failed to fstat core file %s: %m", coredump_tmpfile_name(tmp));
365368
goto fail;
366369
}
367370

@@ -372,8 +375,7 @@ static int save_external_coredump(
372375

373376
#if defined(HAVE_XZ) || defined(HAVE_LZ4)
374377
/* If we will remove the coredump anyway, do not compress. */
375-
if (maybe_remove_external_coredump(NULL, st.st_size) == 0
376-
&& arg_compress) {
378+
if (arg_compress && !maybe_remove_external_coredump(NULL, st.st_size)) {
377379

378380
_cleanup_free_ char *fn_compressed = NULL, *tmp_compressed = NULL;
379381
_cleanup_close_ int fd_compressed = -1;
@@ -705,7 +707,9 @@ static int submit_coredump(
705707

706708
coredump_filename = strjoina("COREDUMP_FILENAME=", filename);
707709
IOVEC_SET_STRING(iovec[n_iovec++], coredump_filename);
708-
}
710+
} else if (arg_storage == COREDUMP_STORAGE_EXTERNAL)
711+
log_info("The core will not be stored: size %zu is greater than %zu (the configured maximum)",
712+
coredump_size, arg_external_size_max);
709713

710714
/* Vacuum again, but exclude the coredump we just created */
711715
(void) coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use);
@@ -730,7 +734,9 @@ static int submit_coredump(
730734
log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno()));
731735
else
732736
log_warning_errno(r, "Failed to generate stack trace: %m");
733-
}
737+
} else
738+
log_debug("Not generating stack trace: core size %zu is greater than %zu (the configured maximum)",
739+
coredump_size, arg_process_size_max);
734740

735741
if (!core_message)
736742
#endif
@@ -740,18 +746,22 @@ static int submit_coredump(
740746
IOVEC_SET_STRING(iovec[n_iovec++], core_message);
741747

742748
/* Optionally store the entire coredump in the journal */
743-
if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
744-
coredump_size <= arg_journal_size_max) {
745-
size_t sz = 0;
746-
747-
/* Store the coredump itself in the journal */
748-
749-
r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz);
750-
if (r >= 0) {
751-
iovec[n_iovec].iov_base = coredump_data;
752-
iovec[n_iovec].iov_len = sz;
753-
n_iovec++;
754-
}
749+
if (arg_storage == COREDUMP_STORAGE_JOURNAL) {
750+
if (coredump_size <= arg_journal_size_max) {
751+
size_t sz = 0;
752+
753+
/* Store the coredump itself in the journal */
754+
755+
r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz);
756+
if (r >= 0) {
757+
iovec[n_iovec].iov_base = coredump_data;
758+
iovec[n_iovec].iov_len = sz;
759+
n_iovec++;
760+
} else
761+
log_warning_errno(r, "Failed to attach the core to the journal entry: %m");
762+
} else
763+
log_info("The core will not be stored: size %zu is greater than %zu (the configured maximum)",
764+
coredump_size, arg_journal_size_max);
755765
}
756766

757767
assert(n_iovec <= n_iovec_allocated);

0 commit comments

Comments
 (0)