我最近开始使用pthread_setname_np()在我的应用程序中设置一些线程名称。执行此操作后,如果在其中一个命名线程中发生崩溃,则核心转储文件名将使用core_pattern%e获取线程名称而不是可执行文件名。%p.core
根据core man page,core_pattern中的%e标志应该扩展为可执行文件名。它没有说明线程名称。
我想要可执行文件名而不是线程名,因为我有其他依赖于以应用程序名称开头的核心文件名的自动化脚本(不是由我维护的)。
这是pthread_setname_np()或core_pattern中的错误吗?
我在Linux CentOS 6.7上运行。
答案 0 :(得分:1)
可以使用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
答案 1 :(得分:0)
所以我通过将核心转储管道传输到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中的一个类的片段。作为奖励,如果您为核心文件名提供.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 :(得分:0)
我有同样的问题。我也以同样的方式解决了问题。 我得到可执行文件名使用/ proc / pid / exe
src_file_path = os.readlink("/proc/%s/exe" %pid)
exec_filename = os.path.basename(src_file_path)