Какой хороший способ выгрузить файл ядра Linux из процесса? - PullRequest
12 голосов
/ 25 ноября 2008

У нас есть сервер (написанный на C и C ++), который в настоящее время перехватывает SEGV и выводит некоторую внутреннюю информацию в файл. Я хотел бы сгенерировать файл ядра и записать его на диск во время захвата SEGV, чтобы нашим представителям службы поддержки и клиентам не приходилось суетиться с ulimit, а затем ждать повторения сбоя, чтобы получить ядро файл. В прошлом мы использовали функцию отмены, но она подчиняется правилам ulimit и не помогает.

У нас есть некоторый устаревший код, который читает / proc / pid / map и вручную генерирует файл ядра, но он устарел и не выглядит очень переносимым (например, я предполагаю, что он не будет работать в наши 64-битные сборки). Каков наилучший способ создания и выгрузки файла ядра в процессе Linux?

Ответы [ 8 ]

9 голосов
/ 03 декабря 2008

В Google есть библиотека для генерации coredumps из запущенного процесса, которая называется google-coredumper . Это должно игнорировать ulimit и другие механизмы.

Документация для вызова, который генерирует основной файл: здесь . Согласно документации, представляется возможным создать файл ядра в обработчике сигналов, хотя не всегда гарантируется его работа.

5 голосов
/ 29 ноября 2008

Я видел сообщение Пмбретта и думал: «Эй, это круто», но я не смог найти эту утилиту нигде в моей системе (Gentoo).

Итак, я немного подтолкнул и обнаружил, что в GDB есть эта опция.

gdb --pid=4049 --batch -ex gcore

Мне показалось, что все работает нормально.

Однако он не очень полезен, потому что он улавливает самую низкую функцию, которая использовалась в то время, но он все еще хорошо справляется с этим (без ограничений памяти, снимок Dumped 350M процесса firefox с ним)

4 голосов
/ 29 ноября 2008

Попробуйте использовать команду Linux gcore

использование: gcore [-o имя_файла] pid

Вам потребуется использовать system (или exec) и getpid (), чтобы создать правильную командную строку для вызова изнутри вашего процесса

3 голосов
/ 26 ноября 2008

Некоторые возможные решения ^ W способы решения этой ситуации:

  1. Исправить ulimit !!!
  2. Примите, что вы не получаете файл ядра и не запускаете внутри GDB, запрограммированный для выполнения "thread all apply bt" на SIGSEGV
  3. Примите, что вы не получили файл ядра и получили трассировку стека из приложения. Статья Backtracing внутри вашей программы довольно старая, но это должно быть возможно и в наши дни.
1 голос
/ 07 сентября 2011

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

void my_handler(int sig)
{
   ...
   if (wantCore_ && !fork()) {
      setrlimit(...);  // ulimit -Sc unlimited
      sigset(sig, SIG_DFL);  // reset default handler
      raise(sig);  // doesn't return, generates a core file
   }
   _exit(1);
}
1 голос
/ 30 декабря 2008

Вы также можете изменить ulimit () из вашей программы с помощью setrlimit (2). Как и команда оболочки ulimit, это может понизить пределы или повысить их настолько, насколько позволяет жесткий предел. При запуске setrlimit (), чтобы разрешить дамп ядра, и все в порядке.

0 голосов
/ 11 ноября 2010

используйте glibc-вызовы backtrace и backtrace_symbols, чтобы получить трассировку, просто имейте в виду, что backtrace_symbols использует malloc внутренне, и в случае повреждения кучи может произойти сбой.

0 голосов
/ 27 марта 2009

система ("убить -6")

Я бы попробовал, если вы все еще ищете что-то

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...