Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a crash-handler.wait-pipe-close parameter #1092

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <pthread.h>
#include <pwd.h>
#include <signal.h>
Expand Down Expand Up @@ -157,6 +158,7 @@ static struct {
char _unused3_avoir_false_sharing[32];
} state;
char *crash_handler;
int crash_handler_wait_pipe_close;
} conf = {
{NULL}, /* globalconf */
RUN_MODE_WORKER, /* dry-run */
Expand All @@ -174,6 +176,7 @@ static struct {
0, /* initialized_threads */
{{0}}, /* state */
"share/h2o/annotate-backtrace-symbols", /* crash_handler */
0, /* crash_handler_wait_pipe_close */
};

static neverbleed_t *neverbleed = NULL;
Expand Down Expand Up @@ -1152,6 +1155,22 @@ static int on_config_crash_handler(h2o_configurator_command_t *cmd, h2o_configur
return 0;
}

static int on_config_crash_handler_wait_pipe_close(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, yoml_t *node)
{
switch (h2o_configurator_get_one_of(cmd, node, "OFF,ON")) {
case 0: /* off */
conf.crash_handler_wait_pipe_close = 0;
break;
case 1: /* on */
conf.crash_handler_wait_pipe_close = 1;
break;
default: /* error */
return -1;
}

return 0;
}

static yoml_t *load_config(yoml_parse_args_t *parse_args, yoml_t *source)
{
FILE *fp;
Expand Down Expand Up @@ -1279,6 +1298,7 @@ static int popen_crash_handler(void)
perror("failed to set FD_CLOEXEC on pipefds[1]");
return -1;
}

/* spawn the logger */
int mapped_fds[] = {pipefds[0], 0, /* output of the pipe is connected to STDIN of the spawned process */
2, 1, /* STDOUT of the spawned process in connected to STDERR of h2o */
Expand Down Expand Up @@ -1306,6 +1326,13 @@ static void on_sigfatal(int signo)
int framecnt = backtrace(frames, sizeof(frames) / sizeof(frames[0]));
backtrace_symbols_fd(frames, framecnt, crash_handler_fd);

if (conf.crash_handler_wait_pipe_close) {
struct pollfd pfd[1];
pfd[0].fd = crash_handler_fd;
pfd[0].events = POLLERR | POLLHUP;
while (poll(pfd, 1, -1) == -1 && errno == EINTR);
}

raise(signo);
}
#endif
Expand Down Expand Up @@ -1738,6 +1765,8 @@ static void setup_configurators(void)
on_config_temp_buffer_path);
h2o_configurator_define_command(c, "crash-handler", H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
on_config_crash_handler);
h2o_configurator_define_command(c, "crash-handler.wait-pipe-close", H2O_CONFIGURATOR_FLAG_GLOBAL | H2O_CONFIGURATOR_FLAG_EXPECT_SCALAR,
on_config_crash_handler_wait_pipe_close);
}

h2o_access_log_register_configurator(&conf.globalconf);
Expand Down
15 changes: 15 additions & 0 deletions srcdoc/configure/base_directives.mt
Original file line number Diff line number Diff line change
Expand Up @@ -642,4 +642,19 @@ standard input of the program.</p>
<p>If the path is not absolute, it is prefixed with <code>${H2O_ROOT}/</code>.</p>
? })

<?
$ctx->{directive}->(
name => "crash-handler.wait-pipe-close",
levels => [ qw(global) ],
desc => q{Whether <code>h2o</code> should wait for the crash handler pipe to close before exiting.},
default => q{crash-handler.wait-pipe-close: OFF},
since => "2.1",
)->(sub {
?>
<p>When this setting is <code>ON</code>, <code>h2o</code> will wait
for the pipe to the crash handler to be closed before exiting.
This can be useful if you use a custom handler that inspects the dying
process.</p>
? })

? })