Jakie są reprezentacje alokacji pamięci w Visual Studio C ++?


216

W Visual Studio wszyscy mieliśmy „baadf00d”, widzieliśmy „CC” i „CD” podczas sprawdzania zmiennych w debuggerze w C ++ w czasie wykonywania.

Z tego, co rozumiem, „CC” jest w trybie DEBUGOWANIA tylko po to, aby wskazać, kiedy pamięć została nowa () lub przydzielona () i zunifikowana. Natomiast „CD” oznacza usuniętą lub zwolnioną pamięć. Widziałem tylko „baadf00d” w wersji RELEASE (ale mogę się mylić).

Od czasu do czasu dochodzimy do sytuacji, w której dochodzi do usuwania wycieków pamięci, przepełnienia bufora itp. I takie informacje są przydatne.

Czy ktoś byłby na tyle uprzejmy, aby wskazać, kiedy iw jakich trybach pamięć jest ustawiona na rozpoznawalne wzorce bajtów do celów debugowania?



@ Lưu Vĩnh Phúc: To nie jest system operacyjny, to debugger. „D” (jak w 0xCD i 0xDD) oznacza Debugowanie (tzn. Malloc_dbg jest nazywane przez malloc, jak wyjaśniono w msdn.microsoft.com/en-us/library/aa270812(v=vs.60).aspx ). Wierzę, że dodaje także ogrodzenie / słupki wokół hałd w celu śledzenia przekroczeń bufora. Bardzo przydatne jest wychwytywanie problemów, gdy występuje błąd podwójnego usuwania lub wielokrotnego zwolnienia (lub nawet możliwego wywołania delete zamiast delete []) i wiszących wskaźników, które zostały usunięte, a podczas inspekcji danych jest to „0xDD” (lub gdy niezainicjowana sterty pokazuje 0xCD)
HidekiAI

Nie powiedziałem, że to system operacyjny. To drugi pytający, który napisał niepoprawnie tytuł
phuclv

Odpowiedzi:


317

Ten link zawiera więcej informacji:

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

* 0xABABABAB: Używany przez HeapAlloc () Microsoftu do oznaczenia bajtów wartowników „ziemia niczyja” po przydzielonej pamięci sterty
* 0xABADCAFE: Uruchomienie tej wartości w celu zainicjowania całej wolnej pamięci w celu przechwycenia błędnych wskaźników
* 0xBAADF00D: Używany przez LocalAlloc firmy Microsoft (LMEM_FIXED) do oznaczania niezainicjowanej przydzielonej pamięci sterty
* 0xBADCAB1E: Kod błędu został zwrócony do debuggera Microsoft eVC, gdy połączenie zostało zerwane z debuggerem
* 0xBEEFCACE: Używany przez Microsoft .NET jako magiczna liczba w plikach zasobów
* 0xCCCCCCCC: Używany przez bibliotekę wykonawczą debugowania Microsoft C ++ do oznaczania niezainicjowanej pamięci stosu
* 0xCDCDCDCD: Używany przez bibliotekę wykonawczą debugowania Microsoft C ++ do oznaczania niezainicjowanej pamięci sterty
* 0xDDDDDDDD: Używany przez stertę debugującą Microsoft C ++ do oznaczania wolnej pamięci sterty
* 0xDEADDEAD: Kod błędu STOP systemu Microsoft Windows używany, gdy użytkownik ręcznie inicjuje awarię.
* 0xFDFDFDFD: Używany przez stertę debugowania Microsoft C ++ do oznaczenia bajtów wartych „ziemi niczyich” przed i po przydzielonej pamięci sterty
* 0xFEEEFEEE: Używany przez HeapFree () Microsoftu do oznaczania wolnej pamięci sterty

20
Widzę tutaj BAADF00D(złe jedzenie), BEEFCACE(wołowe ciasto), BAADCAB1E(zły kabel), BADCAFE(zła kawiarnia) i DEADDEAD(martwy trup). Czy to celowe?
Anderson Green

38
@AndersonGreen Oczywiście to celowe. To się nazywa hexspeak .

28
Kiedyś używaliśmy C0CAC01A, kiedy w przeszłości programowaliśmy na niskim poziomie (jądro systemu operacyjnego) ...;)
Per Lundberg,

2
0xDEADBEEF, 0xC0EDBABEtakże klasyki, nawet jeśli nie wpadły w język ojczysty MS
J. Paulding,

3
Jako fan Paula McCartneya lubięBEA71E5
BlueRaja - Danny Pflughoeft

111

Do przydziałów debugowania dodano całkiem sporo przydatnych informacji. Ta tabela jest bardziej kompletna:

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

Przesunięcie adresu Po HeapAlloc () Po malloc () Podczas darmowych () Po HeapFree () komentarzy
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Informacje o stercie Win32
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00180400 Informacje o stercie Win32
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDDDDDDDD 0x00320448 Ptr do następnego bloku sterty CRT (przydzielonego wcześniej)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 Ptr, aby poprzedni blok sterty CRT (przydzielony później)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Nazwa pliku wywołania malloc ()
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Numer linii wywołania malloc ()
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDDDDDDDD 0xFEEEFEEE Liczba bajtów do malloc ()
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDDDDDDDD 0xFEEEFEEE Typ (0 = uwolniony, 1 = normalny, 2 = użycie CRT itp.)
0x00320FF8 -8 0xBAADF00D 0x00000031 0xDDDDDDDD 0xFEEEFEEE Żądanie nr, wzrasta od 0
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE No mans land
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE 8 bajtów, które chciałeś
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE 8 bajtów, które chciałeś
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE No man land
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDD 0xFEEEFEEE Przydziały sterty Win32 są zaokrąglane w górę do 16 bajtów
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Księgowość sterty Win32
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Księgowość sterty Win32
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Księgowość sterty Win32
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Księgowość sterty Win32
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Księgowość sterty Win32
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Księgowość sterty Win32
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Księgowość sterty Win32
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Księgowość sterty Win32

5

Odnośnie 0xCCa 0xCDw szczególności są to relikty z Intel 8088 / 8086 zestawu instrukcji procesor z powrotem w 1980 roku. 0xCCJest to specjalny przypadek oprogramowanie przerwania opcode . Specjalna wersja jednobajtowa pozwala programowi wygenerować przerwanie 3 .INT 0xCD0xCC

Chociaż numery przerwań oprogramowania są w zasadzie arbitralne, INT 3tradycyjnie używano ich do funkcji debuggera lub funkcji punktu przerwania , która jest konwencją, która obowiązuje do dziś. Za każdym razem, gdy uruchamiany jest debugger, instaluje on moduł obsługi przerwań INT 3, który uruchamia debugger po uruchomieniu tego kodu operacyjnego. Zazwyczaj wstrzymuje aktualnie uruchomione programowanie i wyświetla interaktywny monit.

Zwykle INTkod operacji x86 ma dwa bajty: 0xCDpo którym następuje pożądany numer przerwania od 0-255. Teraz chociaż można wydać 0xCD 0x03na INT 3Intel postanowił dodać specjalną version-- 0xCCbez dodatkowego bajtu - ponieważ kod operacji musi być tylko jeden bajt, aby funkcjonować jako wiarygodnego wypełnienia bajt „” dla nieużywanej pamięci.

Chodzi o to, aby pozwolić na płynne odzyskiwanie, jeśli procesor omyłkowo wskoczy do pamięci, która nie zawiera żadnych zamierzonych instrukcji . Instrukcje wielobajtowe nie nadają się do tego celu, ponieważ błędny skok może wylądować przy dowolnym możliwym przesunięciu bajtu, gdzie musiałby kontynuować z prawidłowo utworzonym strumieniem instrukcji.

Oczywiście jednobajtowe kody operacyjne działają w tym przypadku w sposób trywialny, ale mogą istnieć również dziwaczne wyjątki: na przykład biorąc pod uwagę sekwencję wypełniania 0xCDCDCDCD(również wspomnianą na tej stronie), widzimy, że jest dość niezawodny, ponieważ bez względu na to, gdzie wyląduje wskaźnik instrukcji ( z wyjątkiem być może ostatniego wypełnionego bajtu), procesor może wznowić wykonywanie ważnej dwubajtowej instrukcji x86 CD CD, w tym przypadku w celu wygenerowania przerwania programowego 205 (0xCD).

Dziwniejsze nieruchomo, podczas gdy CD CC CD CC100% interpretacji - daje zarówno INT 3lub INT 204--the sekwencja CC CD CC CDjest mniej pewny, tylko 75%, jak pokazano, ale na ogół 99,99%, gdy powtarza się wypełniacz pamięci int wielkości.

strona z współczesnej instrukcji zestawu instrukcji 8088/8086 pokazująca instrukcję INT
Macro Assembler Reference , 1987


Wow, nie zdawałem sobie sprawy (połącz dwa) 0xCC to INT3. Ma to sens (tzn. Nie przez przypadek). Kiedyś wstawiałem „NOP + INT3” w miejscach, w których są JMP do sprawdzania rejestrów, zanim kilkakrotnie skoczył (dawno temu). Dzięki za ten wgląd, zagadka rozwiązana!
HidekiAI

Po co to było NOP? Czy wpisanie pojedynczego 0xCCbajtu za pomocą polecenia eb(enter bytes) nie wystarczy?
Glenn Slayden,

Po prostu nawyk, wtedy jakiś kod odczytywałby dwa bajty i próbował użyć go jako tabeli skoków, aw niektórych przypadkach, kiedy wymieniam kod zestawu, dodając NOP, nie wyświetlałby się jako „???” lub coś (bardziej czytelnego) podczas demontażu; Podsumowując, z wielu powodów po prostu przyzwyczaił się do wstrzykiwania NOP przed lub po BRK; och, w niektórych przypadkach niektóre aplikacje próbowałyby zrobić sumę kontrolną bloku adresów, więc wyrównałbym JMP $ XYZW za pomocą INT3 + [some-hex] grin
HidekiAI
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.