Что такое хороший способ сбросить файл ядра Linux изнутри процесса?
У нас есть сервер (написанный на C и С++), который в настоящее время ловит SEGV и выдает некоторую внутреннюю информацию в файл. Я хотел бы создать основной файл и записать его на диск в то время, когда мы поймаем SEGV, поэтому наши представители поддержки и клиенты не должны суетиться с помощью ulimit, а затем ждать, когда авария произойдет снова, чтобы получить ядро файл. Мы использовали функцию прерывания в прошлом, но она подчиняется правилам ulimit и не помогает.
У нас есть некоторый унаследованный код, который читает /proc/pid/map и вручную генерирует основной файл, но он устарел и не выглядит очень портативным (например, я предполагаю, что он не будет работать в наши 64-битные сборки). Каков наилучший способ генерации и сброса основного файла в процессе Linux?
Ответы
Ответ 1
В Google есть библиотека для генерации исходных кодов внутри выполняемого процесса google-coredumper. Это должно игнорировать ulimit и другие механизмы.
Документация для вызова, генерирующего файл ядра, здесь. Согласно документации, похоже, что в обработчике сигналов можно создать основной файл, хотя он не всегда будет работать.
Ответ 2
Я увидел сообщение pmbrett и подумал "эй, это круто", но не смог найти эту утилиту где-нибудь в моей системе (Gentoo).
Итак, я немного подтолкнул и обнаружил, что в GDB есть этот параметр.
gdb --pid=4049 --batch -ex gcore
Казалось, что я работаю нормально.
Однако он не очень полезен, потому что он ловушки самой низкой функции, которая использовалась в то время, но она по-прежнему делает хорошую работу за ее пределами (без ограничений памяти, сбрасывается 350M моментальный снимок процесса firefox с ним)
Ответ 3
Попробуйте использовать команду Linux gcore
Использование: gcore [-o имя_файла] pid
Вам нужно будет использовать систему (или exec) и getpid() для создания правильной командной строки, чтобы вызвать ее из вашего процесса
Ответ 4
Некоторые возможные решения ^ W способы решения этой ситуации:
- Исправить ulimit!!!
- Примите, что вы не получите файл ядра и запустите его внутри gdb, чтобы создать "thread all apply bt" на SIGSEGV
- Примите, что вы не получите файл ядра и не получили трассировку стека из приложения. Stack Backtracing Inside Your Program статья довольно старая, но она также должна быть в эти дни.
Ответ 5
Вы также можете изменить ulimit() из вашей программы с помощью setrlimit (2). Как и команда ulimit shell, это может снизить пределы или поднять их так же сильно, как позволяет жесткий предел. При запуске setrlimit() разрешить сброс ядра, и вы в порядке.
Ответ 6
Я предполагаю, что у вас есть обработчик сигналов, который захватывает 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);
}
Ответ 7
( "kill -6" )
Я бы попробовал, если вы все еще ищете что-то
Ответ 8
используйте обратные трассировки backtrace и backtrace_symbols glibc для получения трассировки, просто имейте в виду, что backtrace_symbols использует malloc внутри, а в случае кучного повреждения он может выйти из строя.