Bagaimana cara menggunakan valgrind untuk menemukan kebocoran memori dalam suatu program?
Tolong seseorang bantu saya dan jelaskan langkah-langkah untuk menjalankan prosedur?
Saya menggunakan Ubuntu 10,04 dan saya punya program a.c
, tolong bantu saya.
Jawaban:
Cara Menjalankan Valgrind
Bukan untuk menghina OP, tetapi bagi mereka yang datang ke pertanyaan ini dan masih baru di Linux - Anda mungkin harus menginstal Valgrind pada sistem Anda.
Valgrind siap digunakan untuk kode C / C ++, tetapi bahkan dapat digunakan untuk bahasa lain ketika dikonfigurasi dengan benar (lihat ini untuk Python).
Untuk menjalankan Valgrind , operasikan yang dapat dieksekusi sebagai argumen (bersama dengan parameter apa pun ke program).
Singkatnya, bendera:
--leak-check=full
: "setiap kebocoran individu akan ditampilkan secara detail"--show-leak-kinds=all
: Tunjukkan semua "jenis kebocoran" yang pasti, tidak langsung, mungkin, dapat dicapai dalam laporan "penuh".--track-origins=yes
: Mendukung keluaran yang berguna daripada kecepatan. Ini melacak asal-usul nilai yang tidak diinisialisasi, yang bisa sangat berguna untuk kesalahan memori. Pertimbangkan mematikan jika Valgrind sangat lambat.--verbose
: Dapat memberi tahu Anda tentang perilaku tidak biasa dari program Anda. Ulangi untuk lebih banyak kata.--log-file
: Menulis ke file. Berguna saat output melebihi ruang terminal.Terakhir, Anda ingin melihat laporan Valgrind yang terlihat seperti ini:
Saya mengalami kebocoran, tetapi DI MANA ?
Jadi, Anda mengalami kebocoran memori, dan Valgrind tidak mengatakan sesuatu yang berarti. Mungkin, kira-kira seperti ini:
Mari kita lihat kode C yang saya tulis juga:
Nah, ada 5 byte yang hilang. Bagaimana hal itu terjadi? Laporan kesalahan hanya mengatakan
main
danmalloc
. Dalam program yang lebih besar, itu akan sangat sulit untuk diburu. Ini karena bagaimana executable dikompilasi . Kami benar-benar bisa mendapatkan detail baris demi baris tentang apa yang salah. Kompilasi ulang program Anda dengan bendera debug (saya gunakan digcc
sini):Sekarang dengan build debug ini, Valgrind menunjuk ke baris kode yang tepat mengalokasikan memori yang bocor! (Kata-katanya penting: mungkin tidak persis di mana kebocoran Anda, tetapi apa yang bocor. Jejak membantu Anda menemukan di mana .)
Teknik untuk Debugging Memori Kebocoran & Kesalahan
IndexOutOfBoundsException
mengetik masalah.Kadang-kadang kebocoran / kesalahan Anda dapat dihubungkan satu sama lain, seperti IDE yang menemukan bahwa Anda belum mengetikkan braket penutup. Menyelesaikan satu masalah dapat menyelesaikan yang lainnya, jadi cari yang terlihat sebagai pelakunya yang baik dan terapkan beberapa dari gagasan ini:
gdb
mungkin), dan cari kesalahan prekondisi / postkondisi. Idenya adalah untuk melacak eksekusi program Anda sambil berfokus pada masa pakai memori yang dialokasikan.Pandangan Kebocoran dan Kesalahan Umum
Perhatikan petunjuk Anda
Dan kodenya:
Sebagai asisten pengajar, saya sering melihat kesalahan ini. Siswa menggunakan variabel lokal dan lupa untuk memperbarui pointer asli. Kesalahan di sini adalah memperhatikan bahwa
realloc
sebenarnya dapat memindahkan memori yang dialokasikan di tempat lain dan mengubah lokasi pointer. Kami kemudian pergiresizeArray
tanpa memberi tahu kearray->data
mana array dipindahkan.Tulisan tidak valid
Dan kodenya:
Perhatikan bahwa Valgrind mengarahkan kita ke baris kode yang dikomentari di atas. Array ukuran 26 diindeks [0,25] yang mengapa
*(alphabet + 26)
merupakan penulisan yang tidak valid — di luar batas. Tulisan yang tidak valid adalah hasil umum dari kesalahan satu per satu. Lihatlah sisi kiri operasi tugas Anda.Baca tidak valid
Dan kodenya:
Valgrind mengarahkan kami ke baris komentar di atas. Lihatlah iterasi terakhir di sini, yaitu
*(destination + 26) = *(source + 26);
. Namun,*(source + 26)
sudah di luar batas lagi, sama dengan penulisan yang tidak valid. Pembacaan tidak valid juga merupakan hasil umum dari kesalahan tidak langsung. Lihatlah sisi kanan operasi penugasan Anda.Sumber Terbuka (U / Dys) topia
Bagaimana saya tahu kapan kebocoran itu milik saya? Bagaimana cara menemukan kebocoran saya ketika saya menggunakan kode orang lain? Saya menemukan kebocoran yang bukan milik saya; haruskah saya melakukan sesuatu? Semua adalah pertanyaan yang sah. Pertama, 2 contoh dunia nyata yang menunjukkan 2 kelas pertemuan umum.
Jansson : perpustakaan JSON
Ini adalah program sederhana: ia membaca string JSON dan mem-parsingnya. Dalam pembuatannya, kami menggunakan panggilan pustaka untuk melakukan parsing bagi kami. Jansson membuat alokasi yang diperlukan secara dinamis karena JSON dapat berisi struktur bersarang itu sendiri. Namun, ini tidak berarti kita
decref
atau "membebaskan" memori yang diberikan kepada kita dari setiap fungsi. Faktanya, kode yang saya tulis di atas melontarkan "Pembacaan tidak valid" dan "Penulis tidak valid". Kesalahan itu hilang ketika Anda mengambildecref
garis untukvalue
.Mengapa? Variabel
value
dianggap sebagai "referensi yang dipinjam" di Jansson API. Jansson melacak ingatannya untuk Anda, dan Anda hanya perludecref
struktur JSON yang independen satu sama lain. Pelajaran di sini: baca dokumentasi . Betulkah. Terkadang sulit untuk dipahami, tetapi mereka memberi tahu Anda mengapa hal-hal ini terjadi. Sebagai gantinya, kami memiliki pertanyaan yang ada tentang kesalahan memori ini.SDL : perpustakaan grafik dan permainan
Apa yang salah dengan kode ini ? Secara konsisten kebocoran ~ 212 KiB memori untuk saya. Luangkan waktu sejenak untuk memikirkannya. Kami menghidupkan dan mematikan SDL. Menjawab? Tidak ada yang salah.
Itu mungkin terdengar aneh pada awalnya . Sejujurnya, gambarnya berantakan dan terkadang Anda harus menerima beberapa kebocoran sebagai bagian dari perpustakaan standar. Pelajaran di sini: Anda tidak perlu memadamkan setiap kebocoran memori . Terkadang Anda hanya perlu menekan kebocoran karena itu adalah masalah yang diketahui tidak dapat Anda lakukan . (Ini bukan izin saya untuk mengabaikan kebocoran Anda sendiri!)
Jawaban untuk kekosongan
Bagaimana saya tahu kapan kebocoran itu milik saya?
Ini. (Lagi pula, 99% yakin)
Bagaimana cara menemukan kebocoran saya ketika saya menggunakan kode orang lain?
Peluangnya adalah orang lain sudah menemukannya. Coba Google! Jika itu gagal, gunakan keterampilan yang saya berikan kepada Anda di atas. Jika itu gagal dan Anda sebagian besar melihat panggilan API dan sedikit jejak stack Anda sendiri, lihat pertanyaan berikutnya.
Saya menemukan kebocoran yang bukan milik saya; haruskah saya melakukan sesuatu?
Iya! Sebagian besar API memiliki cara untuk melaporkan bug dan masalah. Gunakan mereka! Bantu memberikan kembali alat yang Anda gunakan dalam proyek Anda!
Bacaan lebih lanjut
Terima kasih sudah tinggal bersamaku selama ini. Saya harap Anda telah mempelajari sesuatu, karena saya mencoba untuk cenderung ke spektrum yang luas dari orang-orang yang tiba pada jawaban ini. Beberapa hal yang saya harap sudah Anda tanyakan: Bagaimana cara kerja pengalokasi memori C? Apa sebenarnya kebocoran memori dan kesalahan memori? Apa bedanya dengan segfault? Bagaimana cara kerja Valgrind? Jika Anda memiliki salah satu dari ini, tolong beri makan rasa ingin tahu Anda:
malloc
, pengalokasi memori Csumber
memcheck
alat diaktifkan secara default?memcheck
adalah alat default:--tool=<toolname> [default: memcheck]
Coba ini:
valgrind --leak-check=full -v ./your_program
Selama valgrind diinstal, ia akan melewati program Anda dan memberi tahu Anda apa yang salah. Ini dapat memberi Anda petunjuk dan perkiraan tempat-tempat di mana kebocoran Anda dapat ditemukan. Jika Anda melakukan segmentasi, coba jalankan
gdb
.sumber
your_program
== nama yang dapat dieksekusi atau perintah apa pun yang Anda gunakan untuk menjalankan aplikasi Anda.Anda dapat menjalankan:
sumber
Anda dapat membuat alias dalam file .bashrc sebagai berikut
Jadi, setiap kali Anda ingin memeriksa kebocoran memori, lakukan saja
Ini akan menghasilkan file log Valgrind di direktori saat ini.
sumber