Trong Visual Studio C ++, các biểu diễn cấp phát bộ nhớ là gì?


216

Trong Visual Studio, tất cả chúng ta đều có "baadf00d", đã thấy "CC" và "CD" khi kiểm tra các biến trong trình gỡ lỗi trong C ++ trong thời gian chạy.

Theo những gì tôi hiểu, "CC" chỉ ở chế độ DEBUG để cho biết khi nào bộ nhớ còn mới () hoặc cấp phát () và được đơn vị hóa. Trong khi "CD" đại diện cho bộ nhớ xóa hoặc miễn phí. Tôi chỉ thấy "baadf00d" trong bản dựng RELEASE (nhưng tôi có thể sai).

Thỉnh thoảng, chúng ta gặp phải tình trạng xử lý rò rỉ bộ nhớ, tràn bộ đệm, v.v. và những loại thông tin này có ích.

Ai đó có đủ tử tế để chỉ ra khi nào và ở chế độ nào bộ nhớ được đặt thành các mẫu byte dễ nhận biết cho mục đích gỡ lỗi không?



@ Lưu Vĩnh Phúc: Đó không phải là HĐH, đó là trình gỡ lỗi. "D" (như trên 0xCD và 0xDD) là dành cho Debug (tức là malloc_dbg là cái được gọi thông qua malloc như được giải thích trong msdn.microsoft.com/en-us/l Library / aa270812 (v = vs.60) .aspx ). Tôi tin rằng nó cũng thêm hàng rào / bài viết xung quanh đống để theo dõi tràn bộ đệm. Nó khá hữu ích để nắm bắt các vấn đề khi bạn gặp lỗi xóa hai lần hoặc nhiều lần (hoặc thậm chí có thể gọi xóa thay vì xóa []) và các con trỏ lơ lửng đã được xử lý và khi bạn kiểm tra dữ liệu, đó là "0xDD" (hoặc khi chương trình chưa được khởi tạo đống 0xCD)
HidekiAI

Tôi không nói đó là HĐH. Đó là người hỏi khác đã viết tittle không chính xác
phuclv

Câu trả lời:


317

Liên kết này có thêm thông tin:

http://en.wikipedia.org/wiki/Magic_number_( lập trình)

* 0xABABABAB: Được sử dụng bởi HeapAlloc () của Microsoft để đánh dấu các byte bảo vệ "không có đất của người đàn ông" sau khi được cấp phát bộ nhớ heap
* 0xABADCAFE: Khởi động đến giá trị này để khởi tạo tất cả bộ nhớ trống để bắt con trỏ sai lầm
* 0xBAADF00D: Được sử dụng bởi LocalAlloc (LMEM_FIXED) của Microsoft để đánh dấu bộ nhớ heap được phân bổ chưa được cấp phép
* 0xBADCAB1E: Mã lỗi được trả về trình gỡ lỗi Microsoft eVC khi kết nối bị cắt đứt với trình gỡ lỗi
* 0xBEEFCACE: Được Microsoft .NET sử dụng làm số ma thuật trong các tệp tài nguyên
* 0xCCCCCCCC: Được sử dụng bởi thư viện thời gian chạy gỡ lỗi C ++ của Microsoft để đánh dấu bộ nhớ ngăn xếp chưa được khởi tạo
* 0xCDCDCDCD: Được sử dụng bởi thư viện thời gian chạy gỡ lỗi C ++ của Microsoft để đánh dấu bộ nhớ heap chưa được khởi tạo
* 0xDĐDĐDĐD: Được sử dụng bởi heap gỡ lỗi C ++ của Microsoft để đánh dấu bộ nhớ heap được giải phóng
* 0xDEADDEAD: Mã lỗi Microsoft Windows STOP được sử dụng khi người dùng tự khởi động sự cố.
* 0xFDFDFDFD: Được sử dụng bởi heap gỡ lỗi C ++ của Microsoft để đánh dấu các byte bảo vệ "không có đất của người đàn ông" trước và sau khi được cấp phát bộ nhớ heap
* 0xFEEEFEEE: Được sử dụng bởi HeapFree () của Microsoft để đánh dấu bộ nhớ heap được giải phóng

19
Ở đây, tôi thấy BAADF00D(thức ăn xấu), BEEFCACE(bánh bò), BAADCAB1E(cáp xấu), BADCAFE(cafe xấu), và DEADDEAD(chết chết). Đây có phải là cố ý?
Anderson Green

38
@AndersonGreen Tất nhiên là cố ý. Nó được gọi là hexspeak .

28
Chúng tôi đã từng sử dụng C0CAC01A khi chúng tôi thực hiện một số chương trình cấp thấp (nhân hệ điều hành) trong những ngày ...;)
Per Lundberg

2
0xDEADBEEF, 0xC0EDBABEcũng là kinh điển ngay cả khi họ không rơi vào ngôn ngữ của MS
J. Paulding

3
Là một người hâm mộ Paul McCartney, tôi rất thíchBEA71E5
BlueRaja - Danny Pflughoeft

111

Thực tế có khá nhiều thông tin hữu ích được thêm vào phân bổ gỡ lỗi. Bảng này đầy đủ hơn:

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

Địa chỉ Offset Sau HeapAlloc () Sau malloc () Trong thời gian miễn phí () Sau HeapFree () Nhận xét
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Thông tin heap Win32
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00180400 Thông tin về đống Win32
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDĐDĐDĐD 0x00320448 Ptr cho khối heap CRT tiếp theo (được phân bổ trước đó)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 Ptr để chặn khối heap CRT (được phân bổ sau này)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Tên tệp của malloc () gọi
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Số cuộc gọi của malloc ()
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDĐDĐDĐD 0xFEEEFEEE Số byte đến malloc ()
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDĐDĐDĐD 0xFEEEFEEE Loại (0 = Giải phóng, 1 = Bình thường, 2 = sử dụng CRT, v.v.)
0x00320FF8 -8 0xBAADF00D 0x00000031 0xDĐDĐDĐD 0xFEEEFEEE Yêu cầu #, tăng từ 0
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDĐDĐDĐD 0xFEEEFEEE Không có đất mans
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDĐDĐDĐD 0xFEEEFEEE 8 byte bạn muốn
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDDDD 0xFEEEFEEE 8 byte bạn muốn
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDĐDĐDĐD 0xFEEEFEEE Không có đất mans
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDDDD 0xFEEEFEEE Phân bổ heap Win32 được làm tròn lên đến 16 byte
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Sổ ghi chép heap Win32
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Sổ ghi chép heap Win32
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Sổ ghi chép heap Win32
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Sổ ghi chép heap Win32
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Sổ ghi chép heap Win32
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Sổ sách kế toán đống Win32
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 sổ sách kế toán đống
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 sổ sách kế toán đống

5

Về 0xCC0xCDđặc biệt, đây là những di tích từ Intel 8088 / 8086 hướng dẫn xử lý bộ trở lại trong năm 1980. 0xCClà một trường hợp đặc biệt của phần mềm ngắt opcode . Phiên bản byte đơn đặc biệt cho phép chương trình tạo ngắt 3 .INT 0xCD0xCC

Mặc dù về nguyên tắc, các số ngắt phần mềm là tùy ý, INT 3được sử dụng cho chức năng ngắt hoặc gỡ lỗi của trình gỡ lỗi , một quy ước còn tồn tại cho đến ngày nay. Bất cứ khi nào trình gỡ lỗi được khởi chạy, nó sẽ cài đặt trình xử lý ngắt để khi opcode đó được thực thi, trình gỡ lỗi sẽ được kích hoạt. Thông thường, nó sẽ tạm dừng chương trình hiện đang chạy và hiển thị lời nhắc tương tác.INT 3

Thông thường, INTopcode x86 là hai byte: 0xCDtheo sau là số ngắt mong muốn từ 0-255. Bây giờ mặc dù bạn có thể phát hành 0xCD 0x03cho INT 3, Intel đã quyết định thêm một đặc biệt version-- 0xCCkhông có byte thêm - bởi vì một opcode phải chỉ có một byte để chức năng như một đáng tin cậy 'điền byte' cho bộ nhớ không sử dụng.

Vấn đề ở đây là cho phép phục hồi một cách duyên dáng nếu bộ xử lý nhảy nhầm vào bộ nhớ không chứa bất kỳ hướng dẫn dự định nào . Các lệnh nhiều byte không phù hợp với mục đích này vì một bước nhảy sai có thể hạ cánh ở bất kỳ độ lệch byte nào có thể xảy ra khi nó phải tiếp tục với luồng lệnh được tạo đúng.

Rõ ràng, các mã một byte hoạt động tầm thường cho việc này, nhưng cũng có thể có các ngoại lệ kỳ quặc: ví dụ, xem xét chuỗi điền 0xCDCDCDCD(cũng được đề cập trên trang này), chúng ta có thể thấy rằng nó khá đáng tin cậy vì dù con trỏ lệnh có hạ cánh ở đâu ( ngoại trừ có lẽ là byte đầy cuối cùng), CPU có thể tiếp tục thực hiện một lệnh x86 hai byte hợp lệ CD CD, trong trường hợp này để tạo ra phần mềm ngắt 205 (0xCD).

Weirder vẫn còn, trong khi CD CC CD CCcó thể hiểu được 100% - đưa ra một INT 3hoặc INT 204- trình tự CC CD CC CDít đáng tin cậy hơn, chỉ 75% như được hiển thị, nhưng nói chung là 99,99% khi được lặp lại dưới dạng bộ nhớ kích thước int.

trang từ sổ tay hướng dẫn sử dụng đồng thời 8088/8086 hiển thị hướng dẫn INT
Tham chiếu trình biên dịch macro , 1987


Ồ, tôi đã không nhận ra (kết nối hai) 0xCC là INT3. Điều đó có ý nghĩa (tức là không phải ngẫu nhiên). Tôi đã từng tiêm "NOP + INT3" vào những nơi có JMP để kiểm tra các thanh ghi trước khi nó nhảy vào một vài lần (cách trở lại khi). Cảm ơn cho cái nhìn sâu sắc, bí ẩn đã giải quyết!
HidekiAI

Cái gì NOPđể làm gì? Sẽ không nhập một 0xCCbyte đơn với lệnh eb(enter byte)?
Glenn Slayden

Chỉ là một thói quen, hồi đó, một số mã sẽ đọc hai byte và cố gắng sử dụng nó làm bảng nhảy hoặc trong một số trường hợp, khi tôi liệt kê mã lắp ráp, bằng cách thêm NOP, nó sẽ không hiển thị dưới dạng '???' hoặc một cái gì đó (dễ đọc hơn) khi tháo rời; tất cả, vì nhiều lý do, nó đã trở thành thói quen chỉ tiêm NOP trước hoặc sau BRK; ồ, trong một số trường hợp, một số ứng dụng sẽ cố kiểm tra khối địa chỉ, vì vậy tôi sẽ cân bằng JMP $ XYZW với INT3 + [some-hex] grin
HidekiAI
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.