How to Change Core Pattern Only for a Particular Application

How to change core pattern only for a particular application?

man core tells us:

Piping core dumps to a program

Since kernel 2.6.19, Linux supports an alternate syntax for the
/proc/sys/kernel/core_pattern file. If the first character of this
file is a pipe symbol (|), then the remainder of the line is
interpreted as a program to be executed. Instead of being written to
a disk file, the core dump is given as standard input to the program.

Note the following points:

  • The program must be specified using an absolute pathname (or a
    pathname relative to the root directory, /), and must immediately
    follow the '|' character.

  • The process created to run the program runs as user and group
    root.

  • Command-line arguments can be supplied to the program (since Linux
    2.6.24), delimited by white space (up to a total line length of
    128 bytes).

  • The command-line arguments can include any of the % specifiers
    listed above. For example, to pass the PID of the process that is
    being dumped, specify %p in an argument.

You can put a script there, like e.g.

| /path/to/myscript %p %s %c

You can detect which process is triggering the coredump: (man core):

       %%  a single % character
%p PID of dumped process
%u (numeric) real UID of dumped process
%g (numeric) real GID of dumped process
%s number of signal causing dump
%t time of dump, expressed as seconds since the Epoch, 1970-01-01
00:00:00 +0000 (UTC)
%h hostname (same as nodename returned by uname(2))
%e executable filename (without path prefix)
%E pathname of executable, with slashes ('/') replaced by exclama‐
tion marks ('!').
%c core file size soft resource limit of crashing process (since
Linux 2.6.24)

Now all you have to do is "do the default thing" for other processes than your own

Change application core dump directory with c program

You can change core dump pattern globally through /proc/sys/kernel/core_pattern.

But if you only want to change the core dump directory of one process, you can do what Apache web server does - register a signal handler that changes the current directory right before core dumping:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/resource.h>

#define COREDUMP_DIR "/tmp"

static void sig_coredump (int sig)
{
struct sigaction sa;

// Change to the directory we want the core to be dumped
chdir (COREDUMP_DIR);

// Clear the signal handler for the signal
memset (&sa, 0, sizeof (sa));
sa.sa_handler = SIG_DFL;
sigemptyset (&sa.sa_mask);
sigaction (sig, &sa, NULL);

// Send the signal again
raise (sig);
}

int main (int argc, char **argv)
{
struct sigaction sa;

// Set up the signal handler for all signals that
// can cause the core dump
memset (&sa, 0, sizeof (sa));
sa.sa_handler = sig_coredump;

sigemptyset (&sa.sa_mask);
sigaction (SIGSEGV, &sa, NULL);
sigaction (SIGBUS, &sa, NULL);
sigaction (SIGABRT, &sa, NULL);
sigaction (SIGILL, &sa, NULL);
sigaction (SIGFPE, &sa, NULL);

// Enable core dump
struct rlimit core_limit;
core_limit.rlim_cur = RLIM_INFINITY;
core_limit.rlim_max = RLIM_INFINITY;

if (setrlimit (RLIMIT_CORE, &core_limit) == -1) {
perror ("setrlimit");
}

// Trigger core dump
raise (SIGSEGV);

return 0;
}

Note that as this relies on the crashing application itself setting up and being able to run the signal handler, it can't be 100% bullet-proof - signal may be delivered before signal handler is set up or signal handling itself may get corrupted.

How to modify the `core_pattern` when building docker image

I needed this myself, I just found out how.
it is not related to docker, but to linux in general.
I am using ubuntu and I am 99% certain centos will behave the same in this regard.

it is edited via sysctl command.

see example

bash$ cat /proc/sys/kernel/core_pattern 
|/usr/share/apport/apport %p %s %c %d %P %E
bash$ sudo sysctl -w kernel.core_pattern="|/usr/share/apport/apport-kde %p %s %c %d %P %E"
kernel.core_pattern = |/usr/share/apport/apport-kde %p %s %c %d %P %E
bash$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport-kde %p %s %c %d %P %E
bash$

note that value starting with | is to express commands. the core dump will be sent to the command as STDIN

Since you asked your question about docker, let me also provide a compatible answer.

FROM centos:7
RUN sudo sysctl -w kernel.core_pattern="core-%e"

for more info on the core pattern you can use in your file, instead of just %e, see https://sigquit.wordpress.com/2009/03/13/the-core-pattern/

also another related question/answer that has more details

https://unix.stackexchange.com/questions/343275/why-is-editing-core-pattern-restricted

Changing location of core dump

Yes, it is. You can change /proc/sys/kernel/core_pattern to define the pathname used to generate the corefile. For more, see man core

example:

echo '/tmp/core_%e.%p' | sudo tee /proc/sys/kernel/core_pattern    # `tee' instead of > so that
# opening happens in the
# elevated process

would cause all future core dumps to be generated in /tmp and be named core_[program].[pid]

How to change the path of, or disable python's core dump?

You can use shell command ulimit to control it:

ulimit -c 0  # Disable core file creation

Without the value, it will print current limit (the maximum size of core file will be created):

ulimit -c

per process configurable core dump directory

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.
*/
}

core kernel pattern %e on Linux appends PID

You need to set kernel.core_uses_pid=0 to avoid having the pid appended when %p is missing.

From core(5):

For backward compatibility, if /proc/sys/kernel/core_pattern does not include %p and /proc/sys/kernel/core_uses_pid (see below) is nonzero, then .PID will be appended to the core filename.

Is it possible to force an existing Java application to use no more than x cores?

It's called setting CPU affinity, and it's an OS setting for processes, not specific to Java.

On Linux: http://www.cyberciti.biz/tips/setting-processor-affinity-certain-task-or-process.html

On Windows: http://www.addictivetips.com/windows-tips/how-to-set-processor-affinity-to-an-application-in-windows/

On Mac it doesn't look like you can set it: https://superuser.com/questions/149312/how-to-set-processor-affinity-on-os-x



Related Topics



Leave a reply



Submit