закрытый символ загружен, но номер строки не отображается? - PullRequest
3 голосов
/ 12 октября 2009

Я использую Windbg для загрузки аварийного дампа из управляемого кода (C #, консольное приложение, созданное для любого процессора), а аварийный дамп создается на платформе x64. Я отлаживаю на платформе x64.

Я использовал следующую команду для загрузки личного символа моего приложения. Вот какие команды я использую в Windbg.

(set symbol path and copy FooService.pdb pdb file to local symbol path D:\Debug)

0:016> .reload /f
.*** WARNING: Unable to verify checksum for FooService.exe
DBGHELP: FooService.pdb- private symbols & lines 
         D:\Debug\FooService.pdb

0:016> lm
start             end                 module name
00000000`00400000 00000000`0041c000   FooService C (private pdb symbols)  D:\Debug\FooService.pdb

Моя путаница заключается в том, что при использовании следующей команды информация о номере строки не отображается в трассировке стека. Есть идеи, что не так? Нужно ли указывать исходный путь?

0:016> ~6 e!clrstack

РЕДАКТИРОВАТЬ 1: Я столкнулся с некоторыми проблемами при использовании! Pe и! U для поиска трассировки стека, где выбрасывается исключение.

Вот мой процесс отладки. Сначала я использую! Pe для печати трассировки стека для объекта исключения, когда я использую! U для дизассемблирования кода. Проблема, которую я нахожу, заключается в том, что! U разберет весь код функции FooService.ProcessOrders (), и я хочу найти точное место, где в функции FooService.ProcessOrders происходит сбой. Я также нахожу, что дизассемблированный аннотированный IL-код содержит только те вызовы функций, которые я сделал (для не-функционального вызова C # кода, например, a = a * 2, показан только язык ассемблера), а не точно IL, сопоставленный каждой строке кода C #, ( 1) это правильное ожидаемое поведение? (2) каково решение или дальнейшее предложение найти точный отказавший код C # из моего анализа, опубликованного здесь?

!pe 0000064280155325

StackTrace (generated):
    SP               IP               Function

    000000001A56DA70 00000642B74E3B7A System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(System.Data.Common.DbAsyncResult, System.String, Boolean)
    000000001A56DB10 00000642B74E3FCC System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
    000000001A56DB90 0000064280155325 FooService.ProcessOrders()
    000000001A56F3E0 0000064280153A21 FooService.RountineJob()

!U 0000064280155325 

спасибо заранее, George

1 Ответ

5 голосов
/ 12 октября 2009

WinDbg / SOS не отображает номера строк в выходные данные !clrstack. Так что, пока lm говорит вам, что у вас есть личные символы pdb для ваших собственных сборок, вы правильно настроили. К сожалению, текущие версии WinDbg / SOS не поддерживают отладку на уровне исходного кода в той же степени, что и для нативного кода.

РЕДАКТИРОВАТЬ: относительно исключений. Когда вы делаете !pe, он сообщит вам стек вызовов, а также смещения соответствующих методов. Если вы берете адрес из столбца IP вывода !pe и набираете !U, вы увидите код JITTED для соответствующего метода. Столбец IP будет последним адресом кода, сгенерировавшего исключение (поэтому вам нужно немного подсчитать, чтобы найти правильную инструкцию).

Демонтированный вывод аннотирован вызовами .NET, поэтому нетрудно сопоставить это с IL или исходным кодом. Это должно помочь вам точно определить, какое выражение броска вы ищете.

При этом вы значительно упростите отладку, если разделите методы на несколько меньших. Если вы сделаете это, имени метода обычно достаточно, чтобы точно определить местоположение исключения. Я понимаю, что это не всегда вариант, но это стоит рассмотреть.

...