




Это зависит от того, какую оболочку вы используете. Если вы используете bash, то команда ulimit управляет несколькими настройками, относящимися к выполнению программы, например, следует ли выгрузить дамп ядра. Если вы напечатаете
ulimit -c unlimited
тогда это скажет bash, что его программы могут выгружать ядра любого размера. Вы можете указать размер, например 52M, вместо неограниченного, если хотите, но на практике в этом нет необходимости, поскольку размер основных файлов, вероятно, никогда не будет для вас проблемой.
В tcsh вы должны ввести
limit coredumpsize unlimited
Извините, но это действительно ответ на ваш вопрос? вы спросили, как сгенерировать, но в нем говорится, как установить пределы
@lzprgmr: Чтобы уточнить: причина, по которой дампы ядра не создаются по умолчанию, заключается в том, что ограничение не установлено и / или установлено на 0, что предотвращает сброс ядра. Устанавливая неограниченный лимит, мы гарантируем, что дамп ядра всегда может быть сгенерирован.
Этот связь идет глубже и дает несколько дополнительных опций для включения генерации дампов ядра в Linux. Единственный недостаток в том, что некоторые команды / настройки остаются невыясненными.
В bash 4.1.2 (1) ограничения выпуска, такие как 52M, не могут быть указаны, что приводит к неверному числовому сообщению об ошибке. На странице руководства указано, что «Значения указаны с шагом 1024 байта».
Ну, у меня был «маленький» проект OpenGL, который однажды сделал что-то странное и вызвал сбой X-сервера. Когда я вернулся, я увидел симпатичный маленький файл ядра на 17 ГБ (на разделе 25 ГБ). Определенно хорошая идея - ограничить размер основного файла :)
У меня вопрос. Я не хочу устанавливать свой безлимитный. Как я могу узнать, какой размер должен допускаться?
@PolarisUser: Если вы хотите убедиться, что ваш раздел не съедается, я рекомендую установить лимит примерно в 1 гиг. Он должен быть достаточно большим, чтобы обрабатывать любой разумный дамп ядра, при этом не угрожая израсходовать все оставшееся пространство на жестком диске.
Я хочу повторить установку лимита для coredumpsize, как человека, которому только что пришлось очистить пару сотен дампов ядра 20G.
внимание: он не сохраняется после выхода пользователя из системы, по крайней мере, в CentOS, вы должны отредактировать /etc/security/limits.conf, если хотите.
и не забудьте поместить это в .bashrc, чтобы вам не приходилось делать это все время.
По умолчанию вы получите файл ядра. Убедитесь, что текущий каталог процесса доступен для записи, иначе основной файл не будет создан.
Под «текущим каталогом процесса» вы подразумеваете $ cwd на момент запуска процесса? ~ / abc> / usr / bin / cat def, если cat вылетает, текущий каталог, о котором идет речь, ~ / abc или / usr / bin?
~ / abc. Хм, комментарии должны быть длиной 15 символов!
Это будет текущий каталог на момент SEGV. Кроме того, процессы, запущенные с другим эффективным пользователем и / или группой, отличным от реального пользователя / группы, не будут записывать файлы ядра.
В конце я подключил gdb к процессу до его сбоя, а затем, когда он получил segfault, я выполнил команду generate-core-file. Это принудительное создание дампа ядра.
Как вы подключили GDB к процессу?
Чтобы ответить Ritwik G, чтобы присоединить процесс к gdb, просто запустите gdb и введите 'attach
(сокращенно ge)
Если у них есть новый вопрос, они должны задать новый вопрос вместо того, чтобы задавать в комментарии.
Странно то, что я уже установил ulimit -c на unlimited, но файл ядра не создается, а файл generate-core-file в сеансе gdb действительно создает файл ядра, спасибо.
Возможно, вы могли бы сделать это таким образом, эта программа является демонстрацией того, как перехватить ошибку сегментации, и передает оболочку отладчику (это исходный код, используемый в AIX) и печатает трассировку стека до точки ошибки сегментации. Вам нужно будет изменить переменную sprintf, чтобы использовать gdb в случае Linux.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <stdarg.h>
static void signal_handler(int);
static void dumpstack(void);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);
struct sigaction sigact;
char *progname;
int main(int argc, char **argv) {
char *s;
progname = *(argv);
atexit(cleanup);
init_signals();
printf("About to seg fault by assigning zero to *s\n");
*s = 0;
sigemptyset(&sigact.sa_mask);
return 0;
}
void init_signals(void) {
sigact.sa_handler = signal_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGSEGV);
sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGBUS);
sigaction(SIGBUS, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGQUIT);
sigaction(SIGQUIT, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGHUP);
sigaction(SIGHUP, &sigact, (struct sigaction *)NULL);
sigaddset(&sigact.sa_mask, SIGKILL);
sigaction(SIGKILL, &sigact, (struct sigaction *)NULL);
}
static void signal_handler(int sig) {
if (sig == SIGHUP) panic("FATAL: Program hanged up\n");
if (sig == SIGSEGV || sig == SIGBUS){
dumpstack();
panic("FATAL: %s Fault. Logged StackTrace\n", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
}
if (sig == SIGQUIT) panic("QUIT signal ended program\n");
if (sig == SIGKILL) panic("KILL signal ended program\n");
if (sig == SIGINT) ;
}
void panic(const char *fmt, ...) {
char buf[50];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, buf);
exit(-1);
}
static void dumpstack(void) {
/* Got this routine from http://www.whitefang.com/unix/faq_toc.html
** Section 6.5. Modified to redirect to file to prevent clutter
*/
/* This needs to be changed... */
char dbx[160];
sprintf(dbx, "echo 'where\ndetach' | dbx -a %d > %s.dump", getpid(), progname);
/* Change the dbx to gdb */
system(dbx);
return;
}
void cleanup(void) {
sigemptyset(&sigact.sa_mask);
/* Do any cleaning up chores here */
}
Возможно, вам придется дополнительно добавить параметр, чтобы gdb выгружал ядро, как показано здесь, в этом блоге здесь.
Есть еще кое-что, что может повлиять на создание дампа ядра. Я столкнулся с такими:
/proc/sys/kernel/core_pattern./proc/sys/fs/suid_dumpable может препятствовать генерации ядра.Есть и другие ситуации, которые могут помешать генерации, которые описаны на странице руководства - попробуйте man core.
Чтобы активировать дамп ядра, выполните следующие действия:
В /etc/profile прокомментируйте строку:
# ulimit -S -c 0 > /dev/null 2>&1
В /etc/security/limits.conf закомментируйте строку:
* soft core 0
выполните cmd limit coredumpsize unlimited и проверьте его с помощью cmd limit:
# limit coredumpsize unlimited
# limit
cputime unlimited
filesize unlimited
datasize unlimited
stacksize 10240 kbytes
coredumpsize unlimited
memoryuse unlimited
vmemoryuse unlimited
descriptors 1024
memorylocked 32 kbytes
maxproc 528383
#
чтобы проверить, записан ли основной файл, вы можете убить соответствующий процесс с помощью cmd kill -s SEGV <PID> (не требуется, на всякий случай, если не будет записан основной файл, это можно использовать в качестве проверки):
# kill -s SEGV <PID>
После того, как corefile был записан, не забудьте снова деактивировать настройки coredump в соответствующих файлах (1./2./3.)!
Как объяснялось выше, настоящий вопрос, который задается здесь, заключается в том, как включить дампы ядра в системе, где они не включены. Здесь дан ответ на этот вопрос.
Если вы пришли сюда в надежде узнать, как сгенерировать дамп ядра для зависшего процесса, ответ будет
gcore <pid>
если gcore недоступен в вашей системе, тогда
kill -ABRT <pid>
Не используйте kill -SEGV, так как это часто вызывает обработчик сигнала, что затрудняет диагностику зависшего процесса.
Я думаю, что гораздо более вероятно, что -ABRT вызовет обработчик сигнала, чем -SEGV, поскольку прерывание с большей вероятностью будет восстановлено, чем ошибка сегментации. (Если вы обрабатываете segfault, обычно он просто запускается снова, как только ваш обработчик завершает работу.) Лучшим выбором сигнала для генерации дампа ядра является -QUIT.
Чтобы проверить, где генерируются дампы ядра, запустите:
sysctl kernel.core_pattern
или же:
cat /proc/sys/kernel/core_pattern
где %e - это имя процесса, а %t - системное время. Вы можете поменять его в /etc/sysctl.conf и перезагрузить sysctl -p.
Если файлы ядра не генерируются (проверьте это: sleep 10 & и killall -SIGSEGV sleep), проверьте ограничения: ulimit -a.
Если размер вашего основного файла ограничен, запустите:
ulimit -c unlimited
сделать его безграничным.
Затем проверьте еще раз, если выгрузка ядра прошла успешно, вы увидите «(core dumped)» после индикации ошибки сегментации, как показано ниже:
Segmentation fault: 11 (core dumped)
См. Также: ядро сброшено - но файл ядра отсутствует в текущем каталоге?
В Ubuntu дампы ядра обрабатываются Аппорт и могут находиться в /var/crash/. Однако в стабильных выпусках он по умолчанию отключен.
Для получения дополнительной информации, пожалуйста, проверьте: Где мне найти дамп ядра в Ubuntu?.
Для macOS см .: Как сгенерировать дампы ядра в Mac OS X?
Для Ubuntu, чтобы быстро вернуться к нормальному поведению (выгрузить файл ядра в текущий каталог), просто остановите службу аппорта с помощью «sudo service apport stop». Также обратите внимание, что если вы работаете в докере, этот параметр контролируется в хост-системе, а не в контейнере.
Для Ubuntu 14.04
Проверьте, включен ли дамп ядра:
ulimit -a
Одна из строк должна быть:
core file size (blocks, -c) unlimited
Если не :
gedit ~/.bashrc и добавьте ulimit -c unlimited в конец файла и сохраните, перезапустите терминал.
Создайте свое приложение с отладочной информацией:
В Makefile -O0 -g
Запустите приложение, которое создает дамп ядра (файл дампа ядра с именем «core» должен быть создан рядом с файлом application_name):
./application_name
Запускаем под gdb:
gdb application_name core
На шаге 3, как «перезапустить» терминал? Вы имеете ввиду перезагрузку?
@Naveen нет, просто закройте терминал и откройте новый, также кажется, что вы можете просто поместить ulimit -c unlimited в терминал для временного решения, потому что только редактирование ~/.bashrc требует перезапуска терминала, чтобы изменения вступили в силу.
Лучше программно включить дамп ядра с помощью системного вызова setrlimit.
пример:
#include <sys/resource.h>
bool enable_core_dump(){
struct rlimit corelim;
corelim.rlim_cur = RLIM_INFINITY;
corelim.rlim_max = RLIM_INFINITY;
return (0 == setrlimit(RLIMIT_CORE, &corelim));
}
почему так лучше?
core-файл, созданный после сбоя, нет необходимости запускать ulimit -c unlimited в среде командной строки, а затем повторно запускать приложение.
Мне не нужен дамп ядра каждый раз, когда он падает, только когда пользователь связывается со мной как разработчиком, чтобы посмотреть на него. Если он выйдет из строя 100 раз, мне не нужно смотреть 100 дампов ядра.
В этом случае лучше использовать ulimit -c unlimited. Также вы можете скомпилировать с определением marco, приложение не будет включать символ enable_core_dump, если не определит этот макрос при выпуске, и вы получите замену дампа ядра отладочной версией.
даже если он определен макросом, это все равно требует от меня перекомпиляции, если я хочу сгенерировать дамп ядра, а не просто выполнить команду в оболочке перед повторным запуском.
Разработчику так удобно получить файл дампа ядра и более подробную отладочную информацию. В выпускной версии обычно компилируется с -O2 и без -g, и отладочная информация удалена или оптимизирована, и я контролирую все параметры отладки и дамп файла ядра, используя это определение marco в CMakeLists.txt или Makefile. У вас может быть свой выбор.
Стоит упомянуть, что если у вас настроен systemd, тогда все будет немного иначе. При настройке обычно основные файлы передаются по конвейеру с помощью значения sysctl core_pattern через systemd-coredump(8). Rlimit размера основного файла обычно уже настроен как "неограниченный".
Затем можно получить дампы ядра с помощью coredumpctl(1).
Хранилище дампов ядра и т.п. настраивается coredump.conf(5). На странице руководства coredumpctl есть примеры того, как получить файлы ядра, но вкратце это будет выглядеть так:
Найдите основной файл:
[vps@phoenix]~$ coredumpctl list test_me | tail -1
Sun 2019-01-20 11:17:33 CET 16163 1224 1224 11 present /home/vps/test_me
Получите файл ядра:
[vps@phoenix]~$ coredumpctl -o test_me.core dump 16163
Ubuntu 19.04
Сами по себе все остальные ответы мне не помогли. Но следующий итог сработал.
Создайте ~/.config/apport/settings со следующим содержимым:
[main]
unpackaged=true
(Это говорит apport также писать дампы ядра для пользовательских приложений)
чек: ulimit -c. Если он выводит 0, исправьте это с помощью
ulimit -c unlimited
На всякий случай перезапустите аппорт:
sudo systemctl restart apport
Файлы сбоев теперь записываются в /var/crash/. Но вы не можешь используете их с gdb. Чтобы использовать их с gdb, используйте
apport-unpack <location_of_report> <target_directory>
Дальнейшая информация:
core_pattern. Имейте в виду, что этот файл может быть перезаписан службой аппорта при перезапуске.ulimit -c может измениться автоматически, пока вы пробуете другие ответы в Интернете. Обязательно проверяйте его регулярно во время настройки создания дампа ядра.Рекомендации:
Как посмотреть дальше: stackoverflow.com/questions/8305866/…