Коли налагодження программи йде в режимі ядра налагоджувач (WinDbg в даному випадку) працює у глобальній області видимості і грубо кажучи не розрізнює процеси. Тому і не можливо в такому режимі просто так встановити точку зупинки (breakpoint).

Тим не менш це можливо з певними додатковими діями.

Спочатку знайдемо ідентифікатор процеса який нас цікавить:

kd>!process 0 0 notepad.exe
PROCESS 8fa35c80  SessionId: 0  Cid: 07b8    Peb: 7fe37000  ParentCid: 0354

Далі переключимося у процес і виконаємо одну команду щоб налагоджувач зупинився саме у нашому процесі:

kd>.process /i 8fa35c80

kd>g

kd>!process –1 0

Тепер можна встановити точку зупинки в поточному процесі:

kd>.reload /user

kd>bp /p 8fa35c80 USER32!GetMessageW

Зауваження: Точку зупинки звісно можна встановити і в режимі ядра, але там не можливо її встановити для конкретного процеса. Наприклад:

kd>bp USER32!GetMessageW

встановить точку зупинки для будь-якого процесу що викликає GetMessage.

 

Ну власне все що треба знати про дебагінг у Windows. Вірніше не те щоб зовсім усе, але доволі багато.

 

ASSERT’и, принципи роботи дебагера, Visual Studio, асемблер x86, креші, тулзи, бібліотеки і сорци, сорци…

http://search.barnesandnoble.com/books/product.aspx?isbn=9780735608863

 

http://www.amazon.com/Debugging-Applications-DV-MPS-Programming-Robbins/dp/0735608865/ref=sr_1_1?ie=UTF8&qid=1297124400&sr=8-1

Створення фрейму (початок блоку __try) виглядає так:

1 push 004060d0h // data value... 2 push 004014a0h // ...and function pointer (__except_handler3) 3 mov eax, fs:[0] // accessing TIB - adding a node to the top... 4 push eax // ...of the cjain 5 mov dword ptr fs:[0], esp // where actual node is

Цей код може бути оптимізовано і в результаті перемішано з іншим кодом:

1 mov eax, fs:[0] 2 push ebp 3 mov ebp, esp 4 push 0ffh 5 push 77f3d1e8h 6 push __except_handler3 7 push eax 8 mov eax, [BaseStaticServerData] 9 mov dword ptr fs:[0], esp

Знищення фрейму компілюється у такий код:

1 mov ecx, dword ptr [ebp-10h] 2 mov dword ptr fs:[0], ecx

Локальні змінні і аргументи функцій розміщуються у стеку (якщо звісно не задіяно якусь оптимізацію):

1 void f(int *p1, int *p2) 2 { 3 // standard function prolog 4 // push ebp 5 // mov ebp, esp 6 // sub esp, 8 <-- 2 local variables, 4 bytes each 7 8 int i1 = 3; 9 // mov dword ptr [ebp-8], 3 10 11 int i2 = 0x42; 12 // mov dword ptr [ebp-4], 42h 13 14 i1 = *p1; 15 // mov eax, dword ptr [ebp+8] 16 // mov ecx, dword ptr [eax] 17 // mov dword ptr[ebp-8], ecx 18 19 i2 = *p2; 20 // mov eax, dword ptr [ebp+0ch] 21 // mov ecx, dword ptr [eax] 22 // mov dword ptr[ebp-4], ecx 23 24 // standard epilogue 25 // mov esp, ebp 26 // pop ebp 27 // ret 28 }

Нехай адреса крешу буде CA. У загальному вигляді алгоритм виглядає так:

  1. Необхідно мати .map-файл, якщо його ще нема то створити. Для цього треба вибрати опцію Line Numbers Only для Debug Info у властивостях проекту. Також треба вказати ключі /MAPINFO:LINES та /MAPINFO:EXPORTS для лінкера. Проект треба перебілдити (вірніше перезібрати).
  2. У .map-файлі треба знайти Preferred load address (PLA).
  3. Далі знаходимо колонку Rva+Base і в ній шукаємо найбільшу адресу яка менша за адресу креша. Таким чином знаходимо ім’я файлу і методу де стався креш.
  4. У секції Line numbers для знайденого файлу шукаємо номер рядка найближчий до значення CA-PLA-0x1000.

Статті по темі:

 Timestamp is 4d2cf75d (Tue Jan 11 16:35:41 2011)

 Preferred load address is 00400000

Start         Length     Name                   Class
0001:00000000 00010000H .textbss                DATA
0002:00000000 000065ceH .text                   CODE
0002:000065d0 00001259H .text$x                 CODE
0003:00000000 00000104H .CRT$XCA                DATA
0003:00000104 00000104H .CRT$XCAA               DATA

  Address         Publics by Value              Rva+Base       Lib:Object

0000:00000000       ___safe_se_handler_count   00000000     <absolute>
0000:00000000       ___safe_se_handler_table   00000000     <absolute>
0000:00000000       ___ImageBase               00400000     <linker-defined>
0001:00000000       __enc$textbss$begin        00401000     <linker-defined>
0001:00010000       __enc$textbss$end          00411000     <linker-defined>
0002:00000740       _main                      00411740 f   test.obj
0002:00000790       ?test_string_assign@@YAXXZ 00411790 f   test.obj
0002:00000940       ??0?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@PBDI@Z 00411940 f i test.obj
0002:00000a10       ??1?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAE@XZ 00411a10 f i test.obj

Щоб дебагер студії міг красиво показати значення об’єктів типу треба додати його опис/форматування в файл AUTOEXP.DAT.

 

Формат наступний: 

type=[text]<member[,format]>…

Field

Description

type

Type name. For  template can be followed by <*> to encompass all derived types.

text

Any

member

Data member or expression.

format

See Formatting Symbols for Watch Window

e.g. _PROC_INFO=hProc=<hProc,X> hThread=<hThread,X>

 

Тобто символи <> треба вводити.

Watch Window Pseudo registers

Pseudo register

Description

@ERR

Last error value (GetLastError result)

@TIB

Thread information block for current thread

@CLK

Clock register

Trick: enter @CLK and @CLK=0.the second zeroes out the timer after continuing debugging.

@EAX, @EBX, @ECX, @EDX, @ESI, @EDI, @EIP, @ESP, @EBP, @EFL

CPU registers

@CS, @DS, @ES, @SS, @FS, @GS

CPU segment registers

@ST0, @ST1, @ST2, @ST3, @ST4, @ST5, @ST6, @ST7

CPU floating-point registers

Formatting Symbols for Watch Window

Symbol

Description

Sample

Displays

d, i

Signed decimal int

(int)0xF000F064,d

-268373915

u

Unsigned decimal int

0x0065,u

101

o

Unsigned octal decimal

0xF065,o

0170145

x, X

Hexidecimal integer

61541,x

0x0000F065

l, h

Long or short prefix for d, I, u, o, x, X

0x0042406042,hx

0x0c22

f

Signed float

3./2,f

1.500000

e

Signed float, scientific notation

3./2,e

1.500000e+00

g

Signed float or signed scientific, which one is shorter

3./2,g

1.5

c

char

0x0065,c

‘e’

s

string

szHiWorlds,z

“Hello world”

su

Unicode string

szWHiWorlds,su

“Hello world”

st

Unicode or ANSI string, dependint on settings in autoext.dat

   

hr

HRESULT or Win32 error code

0,hr

S_OK

wc

Window class flag

0x0040,wc

WC_DEFAULTCHAR

wm

Windows message

0x0010,wm

WM_CLOSE