Sto eseguendo un kernel 2.6.27 personalizzato e ho appena notato che i file core prodotti durante un segfault sono più grandi del limite di dimensione del file rigido definito per i processi.ha effetti non deterministici sui processi
E ciò che lo rende più strano è che il file principale è solo a volte troncato (ma non al limite impostato da ulimit).
Per esempio, questo è il programma cercherò e crash di seguito:
int main(int argc, char **argv)
{
// Get the hard and soft limit from command line
struct rlimit new = {atoi(argv[1]), atoi(argv[1])};
// Create some memory so as to beef up the core file size
void *p = malloc(10 * 1024 * 1024);
if (!p)
return 1;
if (setrlimit(RLIMIT_CORE, &new)) // Set the hard and soft limit
return 2; // for core files produced by this
// process
while (1);
free(p);
return 0;
}
Ed ecco l'esecuzione:
Linux# ./a.out 1446462 & ## Set hard and soft limit to ~1.4 MB
[1] 14802
Linux# ./a.out 1446462 &
[2] 14803
Linux# ./a.out 1446462 &
[3] 14804
Linux# ./a.out 1446462 &
[4] 14807
Linux# cat /proc/14802/limits | grep core
Max core file size 1446462 1446462 bytes
Linux# killall -QUIT a.out
Linux# ls -l
total 15708
-rwxr-xr-x 1 root root 4624 Aug 1 18:28 a.out
-rw------- 1 root root 12013568 Aug 1 18:39 core.14802 <=== truncated core
-rw------- 1 root root 12017664 Aug 1 18:39 core.14803
-rw------- 1 root root 12013568 Aug 1 18:39 core.14804 <=== truncated core
-rw------- 1 root root 12017664 Aug 1 18:39 core.14807
[1] Quit (core dumped) ./a.out 1446462
[2] Quit (core dumped) ./a.out 1446462
[3] Quit (core dumped) ./a.out 1446462
[4] Quit (core dumped) ./a.out 1446462
Così molteplici cose sono successe qui. Ho impostato il limite rigido per ogni processo di circa 1,4 MB.
- I file principali prodotti superano questo limite impostato. Perché?
- E 2 dei 4 file core prodotti vengono troncati, ma esattamente da
4096
byte. Cosa sta succedendo qui?
So che il file principale contiene, tra le altre cose, lo stack completo e la memoria heap allocata. Non dovrebbe essere abbastanza costante per un programma così semplice (dare o prendere qualche byte al massimo), quindi produrre un nucleo coerente tra più istanze?
EDITS:
L'uscita richiesta di du
Linux# du core.*
1428 core.14802
1428 core.14803
1428 core.14804
1428 core.14807
Linux# du -b core.*
12013568 core.14802
12017664 core.14803
12013568 core.14804
12017664 core.14807
Aggiunta memset()
dopo malloc()
sicuramente regnò cose, dal fatto che il file core sono ora tutti troncati a 1449984
(ancora 3522
byte oltre il limite).
Quindi perché prima erano così grandi i nuclei, cosa contenevano? Qualunque cosa fosse, non era soggetta ai limiti del processo.
Il nuovo programma mostra un comportamento interessante vedere:
Linux# ./a.out 12017664 &
[1] 26586
Linux# ./a.out 12017664 &
[2] 26589
Linux# ./a.out 12017664 &
[3] 26590
Linux# ./a.out 12017663 & ## 1 byte smaller
[4] 26653
Linux# ./a.out 12017663 & ## 1 byte smaller
[5] 26666
Linux# ./a.out 12017663 & ## 1 byte smaller
[6] 26667
Linux# killall -QUIT a.out
Linux# ls -l
total ..
-rwxr-xr-x 1 root root 4742 Aug 1 19:47 a.out
-rw------- 1 root root 12017664 Aug 1 19:47 core.26586
-rw------- 1 root root 12017664 Aug 1 19:47 core.26589
-rw------- 1 root root 12017664 Aug 1 19:47 core.26590
-rw------- 1 root root 1994752 Aug 1 19:47 core.26653 <== ???
-rw------- 1 root root 9875456 Aug 1 19:47 core.26666 <== ???
-rw------- 1 root root 9707520 Aug 1 19:47 core.26667 <== ???
[1] Quit (core dumped) ./a.out 12017664
[2] Quit (core dumped) ./a.out 12017664
[3] Quit (core dumped) ./a.out 12017664
[4] Quit (core dumped) ./a.out 12017663
[5] Quit (core dumped) ./a.out 12017663
[6] Quit (core dumped) ./a.out 12017663
In primo luogo, cosa significa "du" per il numero effettivo di byte utilizzati dal file principale? Inoltre, 'memset()' la memoria. Semplicemente facendo 'malloc()' non fa in modo che la memoria reale venga mappata nel processo. –
4096 è la dimensione della pagina della memoria virtuale. Quando viene creato il core dump, tutte le pagine VM assegnate al processo verranno scaricate nel file principale. Il file più piccolo è 2933 pagine e il file più grande è 2934 pagine. Quindi è abbastanza coerente. – user3386109
@AndrewHenle L'aggiunta di 'memset()' ha reso sicuramente le cose più coerenti, ma non del tutto. Ho aggiornato la mia domanda con questo e con i risultati del du. – Ram