2016-01-14 2 views
3

Недавно я начал устанавливать некоторые имена потоков в моем приложении с помощью pthread_setname_np(). После этого, если произошел сбой в одном из именованных потоков, имя файла дампа ядра получает имя потока вместо исполняемого имени с помощью core_pattern% e.% P.coreимя файла core dump получает имя потока вместо имени исполняемого файла с core_pattern% e.% P.core

Согласно core man page, флаг% e в core_pattern предполагается расширить до исполняемого имени. Он ничего не говорит о имени потока.

Я хочу имя исполняемого файла, а не имя потока, потому что у меня есть другие автоматизированные скрипты (не поддерживаемые мной), которые зависят от основных имен файлов, начинающихся с имени приложения.

Это ошибка в pthread_setname_np() или core_pattern?

Я работаю на Linux CentOS 6.7.

+1

Похоже, этот парень имел такую ​​же проблему: http://stackoverflow.com/questions/30866716/generate-core-file-with-original-process -имя – jfritz42

ответ

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, оно сжимает 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 

Я оставлю его в качестве упражнения для читателя о том, как записать остальную часть файла.

1

Имя исполняемого файла, сгенерированное ядро, может быть получено с помощью gdb. следующие печатает его:

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

Или еще лучше использовать Pid% р и/ргос, чтобы получить его. Пример:

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

У меня такая же проблема. И я работал так же. я получаю исполняемое использовать имя файла/Proc/PID/ех

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

 Смежные вопросы

  • Нет связанных вопросов^_^