Dalam Visual Studio C ++, apa representasi alokasi memori?

216

Dalam Visual Studio, kita semua memiliki "baadf00d", telah melihat "CC" dan "CD" ketika memeriksa variabel dalam debugger di C ++ selama run-time.

Dari apa yang saya mengerti, "CC" dalam mode DEBUG hanya untuk menunjukkan kapan memori baru () atau mengalokasikan () dan disatukan. Sedangkan "CD" mewakili memori yang dihapus atau yang bebas. Saya hanya melihat "baadf00d" di RELEASE build (tapi saya mungkin salah).

Sekali-sekali, kita masuk ke situasi mengatasi kebocoran memori, buffer overflows, dll dan informasi seperti ini sangat berguna.

Apakah seseorang akan berbaik hati untuk menunjukkan kapan dan dalam mode apa memori diatur ke pola byte yang dikenali untuk tujuan debugging?

HidekiAI
sumber
@ Lưu Vĩnh Phúc: Ini bukan OS, itu debugger. "D" (seperti pada 0xCD dan 0xDD) adalah untuk Debug (yaitu malloc_dbg adalah apa yang dipanggil melalui malloc seperti yang dijelaskan dalam msdn.microsoft.com/en-us/library/aa270812(v=vs.60).aspx ). Saya percaya ini juga menambahkan pagar / posting di sekitar tumpukan untuk melacak buffer-overruns. Ini cukup berguna untuk menangkap masalah ketika Anda memiliki bug penghapus ganda atau banyak bebas (atau bahkan panggilan hapus alih-alih menghapus []) dan pointer yang menggantung yang telah dibuang dan ketika Anda memeriksa datanya, "0xDD" (atau ketika tumpukan yang tidak diinisialisasi menunjukkan 0xCD)
HidekiAI
Saya tidak mengatakan bahwa itu OS. Penanya lain yang menulis
judulnya secara

Jawaban:

317

Tautan ini memiliki informasi lebih lanjut:

http://en.wikipedia.org/wiki/Magic_number_(programming)

* 0xABABABAB: Digunakan oleh Microsoft HeapAlloc () untuk menandai byte penjaga "no man's land" setelah mengalokasikan memori tumpukan
* 0xABADCAFE: Startup untuk nilai ini untuk menginisialisasi semua memori bebas untuk menangkap pointer yang salah
* 0xBAADF00D: Digunakan oleh Microsoft LocalAlloc (LMEM_FIXED) untuk menandai memori heal yang dialokasikan tidak diinisialisasi
* 0xBADCAB1E: Kode Kesalahan dikembalikan ke Microsoft eVC debugger ketika koneksi terputus ke debugger
* 0xBEEFCACE: Digunakan oleh Microsoft .NET sebagai angka ajaib dalam file sumber daya
* 0xCCCCCCCC: Digunakan oleh perpustakaan runtime debugging C ++ Microsoft untuk menandai memori stack yang belum diinisialisasi
* 0xCDCDCDCD: Digunakan oleh perpustakaan runtime debugging C ++ Microsoft untuk menandai memori tumpukan yang tidak diinisialisasi
* 0xDDDDDDDD: Digunakan oleh tumpukan debugging C ++ Microsoft untuk menandai memori tumpukan yang dibebaskan
* 0xDEADDEAD: Kode galat STOP Microsoft Windows yang digunakan saat pengguna memulai crash secara manual.
* 0xFDFDFDFD: Digunakan oleh tumpukan debugging C ++ Microsoft untuk menandai byte penjaga "no man's land" sebelum dan sesudah mengalokasikan memori tumpukan
* 0xFEEEFEEE: Digunakan oleh Microsoft HeapFree () untuk menandai memori heap yang dibebaskan
Tandai Ingram
sumber
19
Di sini, saya melihat BAADF00D(makanan buruk), BEEFCACE(kue daging sapi), BAADCAB1E(kabel buruk), BADCAFE(kafe buruk), dan DEADDEAD(mati mati). Apakah ini disengaja?
Anderson Green
38
@AndersonGreen Tentu saja disengaja. Ini disebut hexspeak .
28
Kami dulu menggunakan C0CAC01A ketika kami melakukan pemrograman tingkat rendah (kernel sistem operasi) pada masa itu ...;)
Per Lundberg
2
0xDEADBEEF, 0xC0EDBABEjuga klasik bahkan jika mereka tidak termasuk dalam bahasa MS
J. Paulding
3
Sebagai penggemar Paul McCartney, saya sukaBEA71E5
BlueRaja - Danny Pflughoeft
111

Sebenarnya ada sedikit informasi berguna yang ditambahkan ke alokasi debug. Tabel ini lebih lengkap:

http://www.nobugs.org/developer/win32/debug_crt_heap.html#table

Alamat Offset Setelah HeapAlloc () Setelah malloc () Selama bebas () Setelah HeapFree () Komentar
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Win32 info tumpukan
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00110400 Win32 info tumpukan
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDDDDDDDD 0x00320448 Ptr ke blok tumpukan CRT berikutnya (dialokasikan sebelumnya dalam waktu)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 Ptr untuk mencegah blok heap CRT (dialokasikan nanti dalam waktu)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Nama file malloc () panggilan
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Nomor baris panggilan malloc ()
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDDDDDDDD 0xFEEEFEEE Jumlah byte ke malloc ()
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDDDDDDDD 0xFEEEFEEE Jenis (0 = Dibebaskan, 1 = Normal, 2 = penggunaan CRT, dll)
0x00320FF8 -8 0xBAADF00D 0x00000031 0xDDDDDDDD 0xFEEEFEEE Permintaan #, meningkat dari 0
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE Tidak ada lahan
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE 8 byte yang Anda inginkan
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE 8 byte yang Anda inginkan
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE Tidak ada lahan
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDD 0xFEEEFEEE Alokasi heap Win32 dibulatkan hingga 16 byte
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 pembukuan tumpukan
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 pembukuan tumpukan
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Win32 pembukuan tumpukan
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Win32 pembukuan tumpukan
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Win32 pembukuan tumpukan
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Win32 pembukuan tumpukan
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 pembukuan tumpukan
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 pembukuan tumpukan
John Dibling
sumber
5

Mengenai 0xCCdan 0xCDkhususnya, ini adalah peninggalan dari Intel 8088 / 8086 instruksi prosesor set kembali pada 1980-an. 0xCCadalah kasus khusus dari opcode interupsi perangkat lunak . Versi byte tunggal khusus memungkinkan program untuk menghasilkan interrupt 3 .INT 0xCD0xCC

Meskipun angka interupsi perangkat lunak, pada prinsipnya, arbitrer, INT 3secara tradisional digunakan untuk fungsi debugger break atau breakpoint , sebuah konvensi yang masih ada hingga hari ini. Setiap kali debugger diluncurkan, ia menginstal interrupt handler untuk INT 3sedemikian rupa sehingga ketika opcode dijalankan, debugger akan terpicu. Biasanya itu akan menghentikan sementara pemrograman yang sedang berjalan dan menampilkan prompt interaktif.

Biasanya, INTopcode x86 adalah dua byte: 0xCDdiikuti oleh angka interupsi yang diinginkan dari 0-255. Sekarang meskipun Anda bisa mengeluarkan 0xCD 0x03untuk INT 3, Intel memutuskan untuk menambahkan khusus sebuah version-- 0xCCtanpa byte tambahan - karena opcode harus hanya satu byte untuk fungsi sebagai 'mengisi byte' yang handal untuk memori yang tidak terpakai.

Intinya di sini adalah untuk memungkinkan pemulihan yang anggun jika prosesor keliru melompat ke memori yang tidak mengandung instruksi yang dimaksud . Instruksi multi-byte tidak cocok untuk tujuan ini karena lompatan yang salah dapat mendarat pada byte byte yang mungkin di mana ia harus melanjutkan dengan aliran instruksi yang dibentuk dengan benar.

Jelas, satu-byte opcodes bekerja sepele untuk ini, tetapi bisa juga ada pengecualian unik: misalnya, mengingat urutan pengisian 0xCDCDCDCD(juga disebutkan pada halaman ini), kita dapat melihat bahwa itu cukup dapat diandalkan karena di mana pun penunjuk instruksi mendarat ( kecuali mungkin byte terisi terakhir), CPU dapat melanjutkan mengeksekusi instruksi dua-byte x86 yang valid CD CD, dalam hal ini untuk menghasilkan interupsi perangkat lunak 205 (0xCD).

Lebih aneh lagi, sedangkan CD CC CD CC100% dapat ditafsirkan - memberikan salah satu INT 3atau INT 204- urutan CC CD CC CDkurang dapat diandalkan, hanya 75% seperti yang ditunjukkan, tetapi umumnya 99,99% ketika diulang sebagai pengisi memori ukuran int.

halaman dari buku petunjuk set instruksi 8088/8086 kontemporer yang menunjukkan instruksi INT
Referensi Makro Assembler , 1987

Glenn Slayden
sumber
Wow, saya tidak menyadari (menghubungkan keduanya) 0xCC adalah INT3. Itu masuk akal (yaitu bukan karena kebetulan). Saya digunakan untuk menyuntikkan "NOP + INT3" di tempat-tempat di mana ada JMP untuk memeriksa register sebelum melompat pada beberapa kesempatan (jauh ketika). Terima kasih atas wawasan ini, misteri terpecahkan!
HidekiAI
Untuk apa itu NOP? Bukankah memasukkan satu 0xCCbyte dengan perintah eb(enter bytes) sudah cukup?
Glenn Slayden
Hanya kebiasaan, saat itu, beberapa kode akan membaca dua byte dan mencoba menggunakannya sebagai lompatan tabel, atau dalam beberapa kasus, ketika saya daftar kode perakitan, dengan menambahkan NOP, itu tidak akan ditampilkan sebagai '???' atau sesuatu (lebih terbaca) saat dibongkar; Singkatnya, karena berbagai alasan, hanya kebiasaan menyuntikkan NOP sebelum atau sesudah BRK; oh dalam beberapa kasus, beberapa aplikasi akan mencoba untuk melakukan checksum dari blok alamat, jadi saya akan mengimbangi JMP $ XYZW dengan INT3 + [beberapa-hex] seringai
HidekiAI