Jakiś czas temu wzięło mnie na napisanie IDE, w którym możliwe będzie kopilowanie projektów z mieszanymi kompilatorami: różne warianty języków c/c++, assembler oraz basic. Cokolwiek co wypluwa plik .obj lub asm, nada się.

Jako że jakoś już to działa, nadszedł czas na dodanie debuggera. Wybór padł najpierw na systemową funkcją CreateProcess, ale później sięgnąłem po debugeng (serce WinDbg) - ma gotowy assembler, disassembler ... chyba wszystko co trzeba.

Symbole: linker (polink) wypluwa plik .map, który parsuję by zdobyć listę globalnych symboli. Pliki .obj też skanuję by pobrać listę prywatnych symboli, oraz ewentualnie poobgryzać udekorowane symbole, by różne języki były przyjazne sobie nawzajem. Obie listy są łączone w plik .dbg (google:Mar99hood).
BTW skoro mogę oddekorować symbole w .obj, to równie dobrze mogę to zrobić w plikach .lib. I też tak zrobiłem - zrobienie import-library dla dowolnego natywnego .dll to żaden problem - 4 kliki myszką.

Moduł debuggera też już działa pikobelo (screen). Był pisany na zwrór Olly'ego, ma view cpu, rejestry, dump i przełączany stos/callstack. Nawet font jest ten sam.
Do debuggera można załadować programy (exe) i biblioteki (dowolne wariacje .dll). Gdy jest to dll, to debugger zawsze staje w DllMain, odczytanym z headerów. Ale to nie jest tu ważne.

Problem: Gdy debuguję dll który w debugDirectory ma wpisany .pdb, a ja nie mam tego pdb (przykład: flash**.ocx), ale mam plik .map wypluty z IDA, to jestem w stanie przerobić plik .map na .dbg, ale nijak nie mogę załadować pliku .dbg do debuggera. DbgHelp nie szuka pliku .dbg gdy w exe/dll jest wpisany pdb, chociaż nie może go znaleźć.

swprintf(bstrCommand, L"ld %s /f %s", moduleName, dbgFilePath);
IDebugControl4::ExecuteWide(DEBUG_OUTCTL_THIS_CLIENT, bstrCommand, DEBUG_EXECUTE_ECHO);

Zwraca błąd 0x80040205 EVENT_E_INTERNALEXCEPTION i pisze Symbols already loaded for Flash9e, co nie jest prawdą, bo znane są tylko exportowane funkcje.
Skoro twierdzi że załadował symbole, to ja chcę je usunąć i załadować mój zestaw symboli. Tylko jak je usunąć?

  • SymUnloadModule (32/64) zwraca ERROR_INVALID_HANDLE. Ok, może mój thread nie może usuwać symboli, albo ich po prostu nie ma w dbghelp.
  • SymAddSymbol - odpada, nawet najnowsza wersja debugging tools for windows z paczki GRMWDK_EN_7600_1.ISO - WDK 7600.16385.1 jest okropnie wolna w tej funkcji.
  • IDebugSymbolGroup::AddSymbol - porażka. Dodaje jeden symbol co 7 sekund, pożerając CPU.

Została mi jeszcze opcja skopiowania targetu w ustronne miejsce, i zmodyfikowanie debugDirectory, które polega na usunięciu xxx.pdb i wstawieniu xxx.dbg. Metoda wydaje się dużo prostsza od zbudowania osobnej listy symboli, którą będę najpierw odpytywał, a gdy zapytanie zostanie odrzucone, to dopiero wtedy zapytam dbgeng o symbol (IDebugControl3::GetNameByOffsetWide).

Aktualnie puściłem pętlę ładującą symbole ręcznie, z IDebugSymbolGroup::AddSymbol, na CPU chodzącym na pół gwizdka, 800MHz. Od ponad godziny ładuje te symbole, a jest ich tylko 3039.
Ktoś coś wie jak wyładować "symbole" dla danego modułu, albo jak załadować .dbg (albo lepiej, czym skonwertować dbg do pdb :D ) ?