Core dump filename retrieves the stream name instead of the executable name using core_pattern% e.% P.core

I recently started setting some thread names in my application using pthread_setname_np (). After that, if one of the named threads fails, the kernel dump file name gets the thread name instead of the executable name using core_pattern% e.% P.core

According to the main man page, the% e flag in core_pattern should be expanded to an executable name. It does not say anything about the name of the stream.

I want the name of the executable file, not the name of the stream, because I have other automated scripts (not supported by me) that depend on the main file names starting with the name of the application.

Is this a bug in pthread_setname_np () or core_pattern?

I am working on Linux CentOS 6.7.

+4
source share
3 answers

The name of the executable file that generated the kernel can be restored using gdb. The following will print it:

gdb -batch -ex "core corefile" | grep "Core was generated" | cut -d\` -f2 | cut -d"'" -f1 | awk '{print $1}'

Or better yet, use pid% p and / proc to get it. Example:

$ sleep 900 &
[1] 2615
$ readlink /proc/$(pidof sleep)/exe
/bin/sleep
$ basename $(readlink /proc/$(pidof sleep)/exe)
sleep
+1
source

So, I ran into a problem associating the problem with a kernel dump with a Python script, which then renames the name of the main file based on a hard-coded mapping of regular expression patterns of the stream to the name of the executable.

Here's how to connect the kernel to a script:

/sbin/sysctl -q -w "kernel.core_pattern=|/opt/mydirectory/bin/core_helper.py --corefile /opt/mydirectory/coredumps/%e.%p.core"
/sbin/sysctl -q -w "kernel.core_pipe_limit=8"

core_helper.py. , .gz, coredump gzip.

class CoredumpHelperConfig:
    def __init__(self, corefile):
        self.corefile = corefile

    # Work-around: Linux is putting the thread name into the 
    # core filename instead of the executable. Revert the thread name to 
    # executable name by using this mapping.
    # The order is important -- the first match will be used. 
    threadNameToExecutableMapping = [# pattern       , replace
                                      (r'fooThread.*', r'foo'),
                                      (r'barThread.*', r'foo'),
                                    ]

    def processCore(self):
        (dirname, basename) = os.path.split(self.corefile)
        # E.g. fooThread0.21495.core (no compression) or fooThread0.21495.core.gz (compression requested)
        match = re.match(r'^(\w+)\.(\d+)\.(core(\.gz)?)$', basename)
        assert match
        (threadName, pid, ext, compression) = match.groups()
        # Work-around for thread name problem
        execName = threadName
        for (pattern, replace) in CoredumpHelperConfig.threadNameToExecutableMapping:
            match = re.match(pattern, threadName)
            if match:
                execName = re.sub(pattern, replace, threadName)
                break
        self.corefile = os.path.join(dirname, '.'.join([execName, pid, ext]))
        # Pipe the contents of the core into corefile, optionally compressing it
        core = open(self.corefile, 'w')
        coreProcessApp = "tee"
        if(compression):
            coreProcessApp = "gzip"
        p = subprocess.Popen(coreProcessApp, shell=True, stdin=sys.stdin, stdout=core, stderr=core)
        core.close()
        return True

, .

0

I have the same problem. And I worked the same way. I get the executable file name use / proc / pid / exe

src_file_path = os.readlink("/proc/%s/exe" %pid)
exec_filename = os.path.basename(src_file_path)
0
source

Source: https://habr.com/ru/post/1624360/


All Articles