GNU/Linux >> Belajar Linux >  >> Linux

Membuat dan men-debug file dump Linux

Crash dump, memory dump, core dump, system dump ... semuanya menghasilkan hasil yang sama:file yang berisi status memori aplikasi pada waktu tertentu—biasanya saat aplikasi mogok.

Mengetahui cara menangani file-file ini dapat membantu Anda menemukan akar penyebab kegagalan. Bahkan jika Anda bukan seorang pengembang, file dump yang dibuat di sistem Anda bisa sangat membantu (dan juga mudah didekati) dalam memahami perangkat lunak.

Ini adalah artikel praktis, dan Anda dapat mengikuti contoh dengan mengkloning repositori aplikasi contoh dengan:

git clone https://github.com/hANSIc99/core_dump_example.git 

Bagaimana sinyal berhubungan dengan dumps

Lebih banyak sumber daya Linux

  • Lembar contekan perintah Linux
  • Lembar contekan perintah Linux tingkat lanjut
  • Kursus online gratis:Ikhtisar Teknis RHEL
  • Lembar contekan jaringan Linux
  • Lembar contekan SELinux
  • Lembar contekan perintah umum Linux
  • Apa itu container Linux?
  • Artikel Linux terbaru kami

Sinyal adalah semacam komunikasi antarproses antara sistem operasi dan aplikasi pengguna. Linux menggunakan sinyal yang ditentukan dalam standar POSIX. Di sistem Anda, Anda dapat menemukan sinyal standar yang ditentukan di /usr/include/bits/signum-generic.h . Ada juga halaman sinyal manual yang informatif jika Anda ingin lebih banyak menggunakan sinyal dalam aplikasi Anda. Sederhananya, Linux menggunakan sinyal untuk memicu aktivitas lebih lanjut berdasarkan apakah mereka diharapkan atau tidak terduga.

Saat Anda keluar dari aplikasi yang sedang berjalan, aplikasi biasanya akan menerima SIGTERM sinyal. Karena jenis sinyal keluar ini diharapkan, tindakan ini tidak akan membuat dump memori.

Sinyal berikut akan menyebabkan file dump dibuat (sumber:GNU C Library):

  • SIGFPE:Operasi aritmatika yang salah
  • SIGILL:Instruksi ilegal
  • SIGSEGV:Akses penyimpanan tidak valid
  • SIGBUS:Bus error
  • SIGABRT:Kesalahan terdeteksi oleh program dan dilaporkan dengan memanggil abort
  • SIGIOT:Diberi label kuno di Fedora, sinyal ini digunakan untuk memicu pada abort() di PDP-11 dan sekarang dipetakan ke SIGABRT

Membuat file dump

Navigasikan ke core_dump_example direktori, jalankan make , dan jalankan sampel dengan -c1 beralih:

./coredump -c1 

Aplikasi harus keluar dalam keadaan 4 dengan kesalahan:

"Abgebrochen (Speicherabzug geschrieben)" secara kasar diterjemahkan menjadi "Kesalahan segmentasi (core dumped)."

Apakah itu membuat dump inti atau tidak ditentukan oleh batas sumber daya pengguna yang menjalankan proses. Anda dapat mengubah batas sumber daya dengan ulimit perintah.

Periksa setelan saat ini untuk pembuatan core dump:

ulimit -c 

Jika outputnya unlimited , maka itu menggunakan default (disarankan). Jika tidak, perbaiki batas dengan:

ulimit -c unlimited 

Untuk menonaktifkan pembuatan tipe dump inti:

ulimit -c 0 

Nomor tersebut menentukan sumber daya dalam kilobyte.

Apa itu core dumps?

Cara kernel menangani dump inti didefinisikan dalam:

/proc/sys/kernel/core_pattern 

Saya menjalankan Fedora 31, dan di sistem saya, file tersebut berisi:

/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h 

Ini menunjukkan dump inti diteruskan ke systemd-coredump kegunaan. Isi core_pattern dapat sangat bervariasi antara rasa yang berbeda dari distribusi Linux. Ketika systemd-coredump sedang digunakan, file dump disimpan terkompresi di bawah /var/lib/systemd/coredump . Anda tidak perlu menyentuh file secara langsung; sebagai gantinya, Anda dapat menggunakan coredumpctl . Misalnya:

coredumpctl list 

menampilkan semua file dump yang tersedia yang disimpan di sistem Anda.

Dengan coredumpctl dump , Anda dapat mengambil informasi dari file dump terakhir yang disimpan:

[stephan@localhost core_dump_example]$ ./coredump 
Aplikasi dimulai…

(…….)

Pesan:Proses 4598 (coredump) pengguna 1000 inti yang dibuang.

Stack trace of thread 4598:
#0 0x00007f4bbaf22625 __GI_raise (libc.so.6)
#1 0x00007f4bbaf0b8d9 __GI_abort (libc.so.6)
#2 0x00007f4bbaf664af __libc_message (libc.so.6)
#3 0x00007f4bbaf6da9c malloc_printerr (libc.so.6)
#4 0x00007f4bbaf6f49c _int_free (libc.so.6)
#6 0x00000000004013b1 t/a (/home/stephan/Dokumente/core_dump_example/coredump)
#7 0x00007f4bbaf0d1a3 __libc_start_main. 6)
#8 0x0000000000040113e t/a (/home/stephan/Dokumente/core_dump_example/coredump)
Menolak membuang inti ke tty (gunakan pengalihan shell atau tentukan — output).

Ini menunjukkan bahwa proses dihentikan oleh SIGABRT . Jejak tumpukan dalam tampilan ini tidak terlalu detail karena tidak menyertakan nama fungsi. Namun, dengan coredumpctl debug , Anda cukup membuka file dump dengan debugger (secara default GDB). Ketik bt (kependekan dari backtrace) untuk mendapatkan tampilan yang lebih detail:

Core dihasilkan oleh `./coredump -c1'.
Program dihentikan dengan sinyal SIGABRT, Dibatalkan.
#0  __GI_raise (sig=sig@entry=6) di ../sysdeps/unix /sysv/linux/raise.c:50
50  return ret;
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) di ../sysdeps/unix/ sysv/linux/raise.c:50
#1  0x00007fc37a9aa8d9 di __GI_abort () di abort.c:79
#2  0x00007fc37aa054af di __libc_message (action=action@entry=do_abort, fmt=abaort 0x7fc37ab14f4b "%s\n") di ../sysdeps/posix/libc_fatal.c:181
#3  0x00007fc37aa0ca9c di malloc_printerr (str=str@entry=0x7fc37ab130e0 "gratis():pointer tidak valid") di malloc. c:5339
#4  0x00007fc37aa0e49c di _int_free (av=, p=, have_lock=0) di malloc.c:4173
#5  0x000000000040120e di freeSomething(void*) ()
#6  0x0000000000401401 di utama ()

Alamat memori:main() dan freeSomething() cukup rendah dibandingkan dengan frame berikutnya. Karena kenyataan bahwa objek bersama dipetakan ke area di ujung ruang alamat virtual, Anda dapat mengasumsikan bahwa SIGABRT disebabkan oleh panggilan di perpustakaan bersama. Alamat memori dari objek yang dibagikan tidak konstan di antara pemanggilan, jadi tidak masalah jika Anda melihat alamat yang berbeda di antara panggilan.

Jejak tumpukan menunjukkan bahwa panggilan berikutnya berasal dari malloc.c , yang menunjukkan bahwa sesuatu dengan alokasi memori (de-) mungkin salah.

Dalam kode sumber, Anda dapat melihat (bahkan tanpa pengetahuan tentang C++) bahwa ia mencoba membebaskan pointer, yang tidak dikembalikan oleh fungsi manajemen memori. Ini menghasilkan perilaku yang tidak terdefinisi dan menyebabkan SIGABRT :

void freeSomething(void *ptr){
    free(ptr);
}
int nTmp =5;
int *ptrNull =&nTmp;
freeSomething( ptrNull);

Utilitas coredump systemd dapat dikonfigurasi di bawah /etc/systemd/coredump.conf . Rotasi pembersihan file dump dapat dikonfigurasi di /etc/systemd/system/systemd-tmpfiles-clean.timer .

Anda dapat menemukan informasi lebih lanjut tentang coredumpctl di halaman manualnya.

Mengkompilasi dengan simbol debug

Buka Makefile dan komentari bagian terakhir dari baris 9. Sekarang seharusnya terlihat seperti:

CFLAGS =-Wall -Werror -std=c++11 -g 

-g switch memungkinkan kompiler untuk membuat informasi debug. Jalankan aplikasi, kali ini dengan -c2 beralih:

./coredump -c2 

Anda akan mendapatkan pengecualian floating-point. Buka dump di GDB dengan:

coredumpctl debug 

Kali ini, Anda diarahkan langsung ke baris dalam kode sumber yang menyebabkan kesalahan:

Membaca simbol dari /home/stephan/Dokumente/core_dump_example/coredump…
[New LWP 6218]
Core dihasilkan oleh `./coredump -c2'.
Program diakhiri dengan sinyal SIGFPE, pengecualian aritmatika.
#0 0x0000000000401233 di zeroDivide () di main.cpp:29
29 nRes =5 / nDivider;
(gdb)

Ketik list untuk mendapatkan gambaran yang lebih baik tentang kode sumber:

(gdb) list
24      int zeroDivide(){
25          int nDivider =5;
26          int nRes =0;
27          while(n 0) br />28              nDivider--;
29              nRes =5 / nDivider;
30          }
31          kembali nRes;

Gunakan perintah info locals untuk mengambil nilai variabel lokal dari saat aplikasi gagal:

(gdb) info penduduk setempat
nDivider =0
nRes =5

Dalam kombinasi dengan kode sumber, Anda dapat melihat bahwa Anda mengalami pembagian dengan nol:

nRes = 5 / 0 

Kesimpulan

Mengetahui cara menangani file dump akan membantu Anda menemukan dan memperbaiki bug acak yang sulit direproduksi dalam aplikasi. Dan jika itu bukan aplikasi Anda, meneruskan dump inti ke pengembang akan membantunya menemukan dan memperbaiki masalahnya.


Linux
  1. Temukan File dan Direktori di Linux Seperti Profesional

  2. Membuat, Menghapus, dan Mengelola Direktori di Linux

  3. Temukan file dan direktori terbesar di Linux

  1. Cara mengekstrak file .gz dan .tar.gz di Linux

  2. Cara Mengarsipkan dan Mengompresi File di Linux

  3. Pemecahan Masalah Jaringan Linux Dan Debugging?

  1. Linux – Direktori Standar Dan/atau Umum Pada OS Unix/linux?

  2. Linux Hapus File dan Direktori

  3. Membuat dan Menghapus File dan Direktori Di Linux