开发者

per process configurable core dump directory

开发者 https://www.devze.com 2022-12-28 11:08 出处:网络
Is there a way to configure the directory where core dump files are placed for a specific process? I have a daemon process written in C++ for which I would like to configure the core dump directory.

Is there a way to configure the directory where core dump files are placed for a specific process?

I have a daemon process written in C++ for which I would like to configure the core dump directory. Optionally the filename pattern should be configurable, too.

I know about /proc/sys/kernel/core_patte开发者_如何学JAVArn, however this would change the pattern and directory structure globally.

Apache has the directive CoreDumpDirectory - so it seems to be possible.


No, you cannot set it per process. The core file gets dumped either to the current working directory of the process, or the directory set in /proc/sys/kernel/core_pattern if the pattern includes a directory.

CoreDumpDirectory in apache is a hack, apache registers signal handlers for all signals that cause a core dump , and changes the current directory in its signal handler.

/* handle all varieties of core dumping signals */
static void sig_coredump(int sig)
{
    apr_filepath_set(ap_coredump_dir, pconf);
    apr_signal(sig, SIG_DFL);
#if AP_ENABLE_EXCEPTION_HOOK
    run_fatal_exception_hook(sig);
#endif
    /* linuxthreads issue calling getpid() here:
     *   This comparison won't match if the crashing thread is
     *   some module's thread that runs in the parent process.
     *   The fallout, which is limited to linuxthreads:
     *   The special log message won't be written when such a
     *   thread in the parent causes the parent to crash.
     */
    if (getpid() == parent_pid) {
        ap_log_error(APLOG_MARK, APLOG_NOTICE,
                     0, ap_server_conf,
                     "seg fault or similar nasty error detected "
                     "in the parent process");
        /* XXX we can probably add some rudimentary cleanup code here,
         * like getting rid of the pid file.  If any additional bad stuff
         * happens, we are protected from recursive errors taking down the
         * system since this function is no longer the signal handler   GLA
         */
    }
    kill(getpid(), sig);
    /* At this point we've got sig blocked, because we're still inside
     * the signal handler.  When we leave the signal handler it will
     * be unblocked, and we'll take the signal... and coredump or whatever
     * is appropriate for this particular Unix.  In addition the parent
     * will see the real signal we received -- whereas if we called
     * abort() here, the parent would only see SIGABRT.
     */
}


It is possible to make it using the "|command" mechanism of the core_pattern file. The executed command can create the directories and files as needed. The command can be passed the following specifiers in the parameters (cf. man 5 core):

%% a single % character
%c core file size soft resource limit of crashing process
%d dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE
%e executable filename (without path prefix)
%E pathname of executable, with slashes ('/') replaced by exclamation marks ('!')
%g (numeric) real GID of dumped process
%h hostname (same as nodename returned by uname(2))
%i TID of thread that triggered core dump, as seen in the PID namespace in which the thread resides
%I TID of thread that triggered core dump, as seen in the initial PID namespace
%p PID of dumped process, as seen in the PID namespace in which the process resides
%P PID of dumped process, as seen in the initial PID namespace
%s number of signal causing dump
%t time of dump, expressed as seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC)
%u (numeric) real UID of dumped process

For example, it possible to create a script (e.g. named crash.sh) as follow:

#!/bin/bash

# $1: process number on host side (%P)
# $2: program's name (%e)

OUTDIR=/tmp/core/$2
OUTFILE="core_$1"

# Create a sub-directory in /tmp
mkdir -p "$OUTDIR"

# Redirect stdin in a per-process file:
cat > "$OUTDIR"/"$OUTFILE"

exit 0

In the shell:

$ chmod +x crash.sh
$ mv crash.sh /tmp  # Put the script in some place
$ sudo su
# echo '|/tmp/crash.sh %P %e' > /proc/sys/kernel/core_pattern
# cat /proc/sys/kernel/core_pattern
|/tmp/crash.sh %P %e
# exit
$

Create an example program which crashes (e.g. fail.c):

int main(void)
{
  char *ptr = (char *)0;

  *ptr = 'q';

  return 0;

}

Compile the program (make several executables) and adjust the core file size in the current shell:

$ gcc fail.c -o fail1
$ gcc fail.c -o fail2
$ ulimit -c
0
$ ulimit -c unlimited
$ ulimit -c
unlimited

Run the failing programs several times to have multiple processes ids:

$ ./fail1
Segmentation fault (core dumped)
$ ./fail2
Segmentation fault (core dumped)
$ ./fail1
Segmentation fault (core dumped)
$ ./fail2
Segmentation fault (core dumped)

Look at /tmp where the core_pattern redirect the core dumps:

$ ls -l /tmp/core
total 8
drwxrwxrwx 2 root root 4096 nov.    3 15:57 fail1
drwxrwxrwx 2 root root 4096 nov.    3 15:57 fail2
$ ls -l /tmp/core/fail1/
total 480
-rw-rw-rw- 1 root root 245760 nov.    3 15:57 core_10606
-rw-rw-rw- 1 root root 245760 nov.    3 15:57 core_10614
$ ls -l /tmp/core/fail2 
total 480
-rw-rw-rw- 1 root root 245760 nov.    3 15:57 core_10610
-rw-rw-rw- 1 root root 245760 nov.    3 15:57 core_10618
0

精彩评论

暂无评论...
验证码 换一张
取 消