10 ответов:
Это зависит от того, какую оболочку вы используете. Если вы используете bash, то команда ulimit управляет несколькими настройками, связанными с выполнением программы, например, следует ли сбрасывать ядро. Если вы наберете
ulimit -c unlimitedтогда это скажет bash, что его программы могут сбрасывать ядра любого размера. Вы можете указать размер, такой как 52M вместо неограниченного, если хотите, но на практике это не должно быть необходимо, так как размер основных файлов, вероятно, никогда не будет проблемой для вы.
в tcsh, вы бы набрали
limit coredumpsize unlimited
как описано выше реальный вопрос здесь заключается в том, как включить дампы ядра в системе, где они не включены. Вот ответ на этот вопрос.
Если вы пришли сюда в надежде узнать, как создать дамп ядра на зависший процесс, ответ
gcore <pid>Если gcore не доступен в вашей системе, то
kill -ABRT <pid>Не используйте kill-SEGV, так как это часто вызывает обработчик сигнала, что затрудняет диагностику застрявшего процесс
то, что я сделал в конце, было прикрепить gdb к процессу, прежде чем он разбился, а затем, когда он получил segfault я выполнил . Это вынужденная генерация дампа ядра.
может быть, вы могли бы сделать это таким образом, эта программа является демонстрацией того, как поймать ошибку сегментации и оболочки из отладчика (это исходный код, используемый в разделе
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 для сброса ядра, как показано здесь в этом блоге здесь.
чтобы проверить, где генерируются основные дампы, выполните:
sysctl kernel.core_patternздесь
%e- имя процесса, а%tсистемное время. Вы можете изменить его в/etc/sysctl.confи перезагрузкиsysctl -p.если основные файлы не создаются (тест:
sleep 10 &иkillall -SIGSEGV sleep), проверьте лимиты:ulimit -a.если размер вашего основного файла ограничен, запустите:
ulimit -c unlimitedчтобы сделать его неограниченным.
затем проверьте еще раз, если ядро демпинг успешен, вы увидите "(core dumped) " после индикации ошибки сегментации, как показано ниже:
ошибка сегментации: 11 (ядро бросила)
Ubuntu
в Ubuntu обычно дампы обрабатываются
apportin/var/crash/, но в другом формате, однако он не включен по умолчанию в стабильных выпусках. Подробнее читайте на Ubuntu wiki.он использует
core_patternсразу пустить по трубам сброс сердечника в программе:$ cat /proc/sys/kernel/core_pattern |/usr/share/apport/apport %p %s %cтаким образом, даже основные файлы отключены
ulimit,apportбудет по-прежнему захватить аварии (Как включить или отключить приложение?).
macOS
для macOS, см.: как создать дампы ядра в Mac OS X?
есть больше вещей, которые могут повлиять на генерацию дампа ядра. Я столкнулся с такими:
- каталог для дампа должен быть доступен для записи. По умолчанию это текущий каталог процесса, но это может быть изменено путем установки
/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и проверить его с cmdlimit:# 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 #чтобы проверить, записывается ли corefile, вы можете убить соответствующий процесс с помощью cmd
kill -s SEGV <PID>(не должно быть необходимо, на всякий случай нет ядра файл записывается это может быть использовано в качестве проверки):# kill -s SEGV <PID>после записи corefile убедитесь, что вы снова отключили настройки coredump в соответствующих файлах (1./2./3.) !
Для 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
по умолчанию вы получите ключевой файл. Убедитесь, что текущий каталог процесса доступен для записи, или не будет создан основной файл.
лучше включить дамп ядра программно с помощью системного вызова
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)); }
Comments