core dump filename gets thread name instead of executable name with core_pattern %e.%p.core

拜拜、爱过 提交于 2020-01-01 09:45:22

问题


I recently started setting some thread names within my application by using pthread_setname_np(). After doing this, if a crash occurs within one of the named threads, the core dump filename is getting the thread name instead of executable name with core_pattern %e.%p.core

According to the core man page, the %e flag in the core_pattern is supposed to get expanded to the executable name. It doesn't say anything about the thread name.

I want the executable name and not the thread name, because I have other automated scripts (not maintained by me) that depend on the core filenames beginning with the application name.

Is this a bug in pthread_setname_np() or core_pattern?

I am running on Linux CentOS 6.7.


回答1:


The executable name that generated the core can be retrieved by using gdb. The following prints it:

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

Or better yet use the 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



回答2:


So I wound up working around the issue by piping the core dump to a Python script which then renames the core filename based on a hard-coded mapping of thread name regex patterns to executable name.

Here's how to pipe the core 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"

Here's a snippet of a class in core_helper.py. As a bonus, if you give the core filename a .gz extension, it will compress the coredump with 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

I'll leave it as an exercise to the reader on how to write the rest of the file.




回答3:


I have the same problem. And I have worked around with the same way. I get executable filename use /proc/pid/exe

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


来源:https://stackoverflow.com/questions/34801353/core-dump-filename-gets-thread-name-instead-of-executable-name-with-core-pattern

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!