【问题标题】:core dump filename gets thread name instead of executable name with core_pattern %e.%p.core核心转储文件名使用 core_pattern %e.%p.core 获取线程名称而不是可执行文件名称
【发布时间】:2016-01-14 22:57:43
【问题描述】:

我最近开始使用 pthread_setname_np() 在我的应用程序中设置一些线程名称。执行此操作后,如果在其中一个指定线程中发生崩溃,核心转储文件名将获取线程名称,而不是 core_pattern %e.%p.core

的可执行文件名称

根据core man page,core_pattern 中的 %e 标志应该扩展为可执行文件名。它没有说明线程名称。

我想要的是可执行文件名而不是线程名,因为我有其他自动化脚本(不是由我维护的)依赖于以应用程序名开头的核心文件名。

这是 pthread_setname_np() 或 core_pattern 中的错误吗?

我在 Linux CentOS 6.7 上运行。

【问题讨论】:

标签: linux pthreads centos6 core


【解决方案1】:

因此,我通过将核心转储传送到 Python 脚本来解决此问题,然后根据线程名称正则表达式模式到可执行名称的硬编码映射重命名核心文件名。

以下是将核心通过管道传输到脚本的方法:

/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 中一个类的 sn-p。作为奖励,如果您为核心文件名提供 .gz 扩展名,它将使用 gzip 压缩 coredump。

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

我将把它作为练习留给读者如何编写文件的其余部分。

【讨论】:

    【解决方案2】:

    可以使用 gdb 检索生成核心的可执行文件名称。 下面打印出来:

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

    或者更好的是使用 pid %p 和 /proc 来获取它。示例:

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

    【讨论】:

      【解决方案3】:

      我也有同样的问题。我也以同样的方式工作过。 我得到可执行文件名使用 /proc/pid/exe

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

      【讨论】:

        猜你喜欢
        • 2012-09-19
        • 2018-07-09
        • 2020-08-17
        • 2016-01-02
        • 1970-01-01
        • 1970-01-01
        • 2012-10-24
        • 1970-01-01
        • 2011-03-27
        相关资源
        最近更新 更多