[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[hurd] 19/19: trans/crash: core file name templates
From: |
Samuel Thibault |
Subject: |
[hurd] 19/19: trans/crash: core file name templates |
Date: |
Wed, 10 Aug 2016 00:05:51 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch upstream
in repository hurd.
commit 02f5c0208985d60fede08c1eafad04e80353b670
Author: Justus Winter <address@hidden>
Date: Fri Jun 3 00:52:06 2016 +0200
trans/crash: core file name templates
Add an option to specify a template used to construct core file names.
This way core files can be collected at a predictable central
location.
* hurd/crash.defs (crash_dump_task): Return EEXIST if the core file
has been written elsewhere.
* trans/crash.c (corefile_template): New variable.
(template_valid): New function.
(template_make_file_name): Likewise.
(S_crash_dump_task): Use the template to construct a name, open the
file, and write the core dump there instead of the handle provided by
the caller.
(argp_option): New option.
(doc): Document the format.
(parse_opt): Handle new option
(trivfs_append_args): Likewise.
---
hurd/crash.defs | 6 +-
trans/crash.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 168 insertions(+), 4 deletions(-)
diff --git a/hurd/crash.defs b/hurd/crash.defs
index 442957d..4295861 100644
--- a/hurd/crash.defs
+++ b/hurd/crash.defs
@@ -25,8 +25,10 @@ subsystem crash 32000;
/* Handle a crashing task, whose task control port is TASK.
- FILE is a file port open for writing. The caller will link it to "core"
- (or whatever name) if the RPC returns success.
+ FILE is a file port open for writing. The caller will link it to
+ "core" (or whatever name) if the RPC returns success. If EEXIST is
+ returned, the core file has been written to a different file,
+ therefore FILE can be discarded.
SIGNO, SIGCODE, and SIGERROR indicate the signal that killed the
process. EXC is zero for a software signal; otherwise EXC, CODE, and
diff --git a/trans/crash.c b/trans/crash.c
index 058d15e..14783cf 100644
--- a/trans/crash.c
+++ b/trans/crash.c
@@ -70,7 +70,105 @@ enum crash_action
#define CRASH_ORPHANS_DEFAULT crash_corefile
static enum crash_action crash_how, crash_orphans_how;
+static char *corefile_template;
+
+
+/* Template parsing. */
+static int
+template_valid (const char *template, const char **errp)
+{
+ int valid = 0;
+ const char *t;
+ int specifier = 0;
+
+ for (t = template; *t; t++)
+ {
+ if (specifier)
+ switch (*t)
+ {
+ case '%':
+ case 'p':
+ case 's':
+ case 't':
+ specifier = 0;
+ break;
+ default:
+ goto out;
+ }
+ else if (*t == '%')
+ specifier = 1;
+ }
+
+ out:
+ valid = ! specifier;
+ *errp = valid? NULL: t;
+ return valid;
+}
+
+static char *
+template_make_file_name (const char *template,
+ task_t task,
+ int signo)
+{
+ const char *t;
+ char *file_name = NULL;
+ size_t file_name_len = 0;
+ FILE *stream;
+ int specifier = 0;
+
+ if (! template_valid (template, &t))
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ stream = open_memstream (&file_name, &file_name_len);
+ if (stream == NULL)
+ return NULL;
+
+ for (t = template; *t; t++)
+ {
+ if (specifier)
+ {
+ switch (*t)
+ {
+ case '%':
+ fprintf (stream, "%%");
+ break;
+
+ case 'p':
+ fprintf (stream, "%d", task2pid (task));
+ break;
+
+ case 's':
+ fprintf (stream, "%d", signo);
+ break;
+
+ case 't':
+ fprintf (stream, "%d", time (NULL));
+ break;
+
+ default:
+ assert (!"reached!");
+ }
+ specifier = 0;
+ }
+ else if (*t == '%')
+ specifier = 1;
+ else
+ fprintf (stream, "%c", *t);
+ }
+
+ assert (! specifier);
+
+ fprintf (stream, "%c", 0);
+ fclose (stream);
+
+ return file_name;
+}
+
+
/* This is defined in ../exec/elfcore.c, or we could have
different implementations for other formats. */
@@ -237,10 +335,42 @@ S_crash_dump_task (mach_port_t port,
err = task_suspend (task);
if (!err)
{
- err = dump_core (task, core_file,
+ file_t sink = core_file;
+ if (corefile_template)
+ {
+ char *file_name;
+
+ file_name = template_make_file_name (corefile_template,
+ task, signo);
+ if (file_name == NULL)
+ error (0, errno, "template_make_file_name");
+ else
+ {
+ sink = file_name_lookup (file_name, O_WRONLY|O_CREAT,
+ S_IRUSR);
+ if (! MACH_PORT_VALID (sink))
+ {
+ error (0, errno, "%s", file_name);
+ sink = core_file;
+ }
+ free (file_name);
+ }
+ }
+
+ err = dump_core (task, sink,
(off_t) -1, /* XXX should get core limit in RPC */
signo, sigcode, sigerror);
task_resume (task);
+
+ if (sink != core_file)
+ {
+ mach_port_deallocate (mach_task_self (), sink);
+
+ /* We return an error so that the libc discards
+ CORE_FILE. */
+ if (! err)
+ err = EEXIST;
+ }
}
break;
@@ -450,13 +580,25 @@ static const struct argp_option options[] =
{"kill", 'k', 0, 0, "Kill the process", 2},
{"core-file", 'c', 0, 0, "Dump a core file", 2},
{"dump-core", 0, 0, OPTION_ALIAS },
+ {"core-file-name", 'C', "TEMPLATE", 0,
+ "Specify core file name (see below)", 2},
{0}
};
static const char doc[] =
"Server to handle crashing tasks and dump core files or equivalent.\v"
"The ACTION values can be `suspend', `kill', or `core-file'.\n\n"
"If `--orphan-action' is not specified, the `--action' value is used for "
-"orphans. The default is `--action=suspend --orphan-action=core-file'.";
+"orphans. The default is `--action=suspend --orphan-action=core-file'.\n"
+"\n"
+"The core file is either written to the file provided by the "
+"crashing process, or if a TEMPLATE value is given, to the file "
+"with the name constructed by expanding TEMPLATE value. "
+"TEMPLATE may contain % specifiers:\n"
+"\n"
+"\t%% just %\n"
+"\t%p the process' PID\n"
+"\t%s the signal number that caused the dump\n"
+"\t%t time of crash in seconds since the EPOCH\n";
static error_t
parse_opt (int opt, char *arg, struct argp_state *state)
@@ -494,6 +636,14 @@ parse_opt (int opt, char *arg, struct argp_state *state)
case 's': crash_how = crash_suspend; break;
case 'k': crash_how = crash_kill; break;
case 'c': crash_how = crash_corefile; break;
+ case 'C':
+ {
+ char *errp;
+ if (! template_valid (arg, &errp))
+ error (1, 0, "Invalid template: ...'%s'", errp);
+ }
+ corefile_template = arg;
+ break;
case ARGP_KEY_SUCCESS:
if (crash_orphans_how == crash_unspecified)
@@ -536,6 +686,18 @@ trivfs_append_args (struct trivfs_control *fsys,
err = argz_add (argz, argz_len, opt);
}
+ if (!err && corefile_template)
+ {
+ char *template;
+ if (asprintf (&template, "--core-file-name=%s", corefile_template) < 0)
+ err = errno;
+ else
+ {
+ err = argz_add (argz, argz_len, template);
+ free (template);
+ }
+ }
+
return err;
}
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/hurd.git
- [hurd] branch upstream updated (04cfa52 -> 02f5c02), Samuel Thibault, 2016/08/09
- [hurd] 18/19: Support MSG_DONTWAIT in pflocal send/recv, Samuel Thibault, 2016/08/09
- [hurd] 19/19: trans/crash: core file name templates,
Samuel Thibault <=
- [hurd] 05/19: Revert "drop the deprecated malloc/free hooks in hurd/mach-defpager", Samuel Thibault, 2016/08/09
- [hurd] 09/19: trans/crash: fix resource leaks, Samuel Thibault, 2016/08/09
- [hurd] 06/19: Complete allocation hooks, Samuel Thibault, 2016/08/09
- [hurd] 12/19: pfinet: fix memory leak, Samuel Thibault, 2016/08/09
- [hurd] 13/19: proc: Fix references to the startup server., Samuel Thibault, 2016/08/09
- [hurd] 02/19: ext2fs: fix pager use-after-free, Samuel Thibault, 2016/08/09
- [hurd] 01/19: libdiskfs: fix error handling, Samuel Thibault, 2016/08/09
- [hurd] 07/19: Fix pipe_send() with no data, Samuel Thibault, 2016/08/09
- [hurd] 11/19: trans/crash: fix blunder, Samuel Thibault, 2016/08/09
- [hurd] 16/19: proc: Fix permission check., Samuel Thibault, 2016/08/09