Saya sedang debug menggunakan core dumps, dan perhatikan bahwa gdb mengharuskan Anda untuk memasok file executable dan juga core dump. Kenapa ini? Jika core dump berisi semua memori yang digunakan proses, bukankah file executable terdapat di dalam core dump? Mungkin tidak ada jaminan bahwa seluruh exe dimuat ke dalam memori (executable individual biasanya tidak sebesar itu) atau mungkin core dump tidak mengandung semua memori yang relevan? Apakah itu untuk simbol (mungkin mereka tidak dimuat ke memori secara normal)?
11
Jawaban:
Core dump hanyalah dump dari jejak memori program Anda, jika Anda tahu di mana semuanya berada maka Anda bisa menggunakannya.
Anda menggunakan executable karena itu menjelaskan di mana (dalam hal alamat logis) hal-hal berada di memori, yaitu file inti.
Jika Anda menggunakan perintah,
objdump
itu akan membuang data meta tentang objek yang dapat dieksekusi yang Anda selidiki. Menggunakan objek yang dapat dieksekusi bernama a.out sebagai contoh.objdump -h a.out
hanya membuang informasi tajuk, Anda akan melihat bagian bernama mis. DATA atau .bss atau .text (masih banyak lagi). Ini menginformasikan kernel loader di mana dalam objek berbagai bagian dapat ditemukan dan di mana dalam ruang alamat proses bagian harus dimuat, dan untuk beberapa bagian (misalnya. Data .text) apa yang harus dimuat. (Bagian .bss tidak mengandung data apa pun dalam file tetapi mengacu pada jumlah memori yang akan disimpan dalam proses untuk data yang tidak diinisialisasi, itu diisi dengan nol).Tata letak file objek yang dapat dieksekusi sesuai dengan standar, ELF.
objdump -x a.out
- kesedihan segalanyaJika objek yang dapat dieksekusi masih berisi tabel simbolnya (belum dilucuti -
man strip
dan Anda digunakan-g
untuk menghasilkan generasi debug dengangcc
asumsi kompilasi sumber ac), maka Anda dapat memeriksa konten inti dengan nama simbol, misalnya jika Anda memiliki variabel / buffer bernama inputLine di kode sumber Anda, Anda bisa menggunakan nama itugdb
untuk melihat kontennya. yaitugdb
akan mengetahui offset dari awal program Anda menginisialisasi segmen data di mana inputLine dimulai dan panjang variabel itu.Bacaan lebih lanjut Article1 , Pasal 2 , dan untuk spesifikasi Executable and Linking Format (ELF) yang sangat diperlukan .
Perbarui setelah komentar @mirabilos di bawah ini.
Tetapi jika menggunakan tabel simbol seperti pada
Menghasilkan
dan kemudian tidak menggunakan tabel simbol dan memeriksa alamat langsung di,
Menghasilkan
Saya telah memeriksa memori secara langsung tanpa menggunakan tabel simbol pada perintah ke-2.
Saya juga melihat, jawaban @ user580082 menambah penjelasan lebih lanjut, dan akan dimutakhirkan.
sumber
File inti adalah snapshot dari gambar tumpukan, pemetaan memori dan register pada saat penghentian proses. Konten yang dapat dimanipulasi seperti yang diberikan dalam halaman manual inti . Secara default pemetaan pribadi, pemetaan bersama dan informasi header ELF dibuang ke file inti.
Datang ke pertanyaan Anda , alasan bahwa gdb memerlukan executable adalah karena ia tidak mensimulasikan eksekusi, dengan membaca dan menafsirkan instruksi biner seperti valgrind yang sebaliknya menjadi induk dari proses sehingga untuk mengontrol perilaku proses selama menjalankan waktu. Ini menggunakan file inti untuk menentukan pemetaan memori dan keadaan proses prosesor selama crash.
Dalam Linux induk proses dapat memperoleh informasi tambahan tentang anak-anak mereka, khususnya kemampuan untuk melacak mereka yang memungkinkan debugger untuk mengakses informasi tingkat proses yang rendah seperti membaca / menulis ingatannya, register, mengubah pemetaan sinyal, menghentikan pelaksanaannya dll.
Anda akan memahami persyaratan yang dapat dieksekusi walaupun memiliki file inti lebih banyak setelah Anda membaca cara kerja setiap debugger.
sumber
(selain jawaban bagus lainnya)
Pada sistem Linux modern (dan banyak yang mirip Unix), informasi debug (termasuk meta-data tentang jenis simbol, lokasi kode sumber, jenis variabel, dll.) Dalam format DWARF dan duduk di dalam ELF yang dapat dieksekusi ( atau pustaka bersama ELF) saat dikompilasi dengan beberapa
-g
opsi. Saya merekomendasikan untuk mengkompilasi program yang akan di-debug-g3 -O0
dan mungkin-fno-inline
jika menggunakan GCC baru-baru ini ; namun, dengan GCC Anda bahkan dapat mengkompilasi dengan kedua informasi pengoptimalan & debugging, mis. dengan-O2 -g1
, meskipun info debug dalam kasus itu mungkin sedikit "kabur" (ini mungkin sedikit membantu untuk menangkap beberapa Heisenbugs nakal ).Sangat masuk akal untuk menghindari menempatkan informasi itu dalam file inti , karena Anda mungkin memiliki banyak file inti yang berbeda (bayangkan perangkat lunak yang banyak digunakan dengan banyak pengguna membuat laporan bug, kebanyakan dari mereka dengan
core
dump) untuk dieksekusi yang sama. Juga file inti (5) dibuang oleh kernel, yang seharusnya tidak peduli tentang keberadaan bagian DWARF di elf (5) yang dapat dieksekusi (karena bagian ini tidak dipetakan ke dalam ruang alamat virtual dari proses kesalahan yang membuang inti pada beberapa sinyal ( 7) ). Bahkan ada kemungkinan untuk memiliki informasi debug yang dimasukkan ke dalam file terpisah (di luar yang dapat dieksekusi).BTW, GDB dapat digunakan dengan menyakitkan untuk men-debug dump inti untuk executable tanpa informasi debug. Tetapi kemudian Anda secara praktis melakukan debug pada level kode mesin (bukan pada level simbolik yang disediakan oleh bahasa pemrograman dan kompilernya).
sumber