Шаг 29 - Как рассчитать строку ошибки по MAP файлу

Итак, мы специально прервем программу в одной из функций:

BOOL CTestDebugDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;
	AfxDebugBreak();
	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}

Ошибка не заставит себя ждать.

29_1.gif (9211 b)

В результате мы видим, что адрес ошибки 0x004026fd. Нам нужно найти первый превосходящий адрес в таблице адресов. Смотрим.

0001:000016d0       ?OnNewDocument@CTestDebugDoc@@UAEHXZ 004026d0 f   TestDebugDoc.obj
0001:00001730       ?Serialize@CTestDebugDoc@@UAEXAAVCArchive@@@Z 00402730 f   TestDebugDoc.obj
0001:00001780       ?AssertValid@CTestDebugDoc@@UBEXXZ 00402780 f   TestDebugDoc.obj

Отсюда видно что первый адрес, который превосходит это – 00402730. Значит предыдущий адрес это та функция, в которой была ошибка – OnNewDocument. Отлично функцию определили и вроде ту, в которой сами ошибку и вызвали. Теперь нужна строка. Нам нужен начальный адрес. Вот где он есть:

.....
TestDebug
Timestamp is 3daba0ac (Tue Oct 15 14:59:24 2002)
Preferred load address is 00400000
.....

Из адреса ошибки вычитаем этот адрес и смещение PE заголовка.

0x004026fd - 00400000-0x1000= 16FD

Теперь этот адрес можно найти в списке строк.

Line numbers for .\Debug\TestDebugDoc.obj(D:\TEMP\TestDebug\TestDebugDoc.cpp) segment .text

    18 0001:00001420    18 0001:000014d0    18 0001:00001500    20 0001:00001540
    20 0001:00001570    31 0001:000015b0    34 0001:000015de    37 0001:00001680
    38 0001:000016a6    41 0001:000016d0    42 0001:000016ed    43 0001:000016f9
    44 0001:000016fd    48 0001:000016fe    49 0001:00001703    57 0001:00001730
    58 0001:0000174d    66 0001:00001755    73 0001:00001780    74 0001:0000179d
    75 0001:000017a5    78 0001:000017d0    79 0001:000017ed    80 0001:000017f9

Вот строка 44. И правда в коде именно эта строка.

29_2.gif (7241 b)


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 15.10.2002