2013-06-17 6 views
1

Я столкнулся с проблемой при попытке использовать DebugDiag для создания дампа при возникновении первого события OutOfMemoryException. Поэтому я написал заявление, что я мог бы использовать для создания отказа от состояния памяти и следуйте приведенным ниже инструкциям:Проблемы с дампом при первом срабатывании OutOfMemoryException

http://blogs.msdn.com/b/kaushal/archive/2012/05/09/using-debugdiag-to-capture-a-dump-on-first-chance-exception.aspx

Но я не получить первый шанс дампа, я просто получить второй шанс- свалка. Когда я смотрю на лог-файлы из DebugDiag я получаю это:

[6/16/2013 9:54:04 PM] First chance exception - 0xe06d7363 caused by thread with System ID: 4628 
[6/16/2013 9:54:04 PM] First chance exception - 0xe0434352 caused by thread with System ID: 4628 
[6/16/2013 9:54:05 PM] Unable to determine CLR exception type 

ExceptionObjHexAddr = 0x00000000`00000000 

bInnerException = False 

DumpObject Output = Invalid parameter 0x00000000`00000000 


ChildEBP RetAddr Args to Child    
002bdee4 6a44c93f e0434352 00000001 00000005 KERNELBASE!RaiseException+0x58 
002bdf88 6a573b17 00000000 20b578f4 002be04c clr!RaiseTheExceptionInternalOnly+0x276 
002bdfb8 6a5e5589 20b54734 002be090 00000000 clr!UnwindAndContinueRethrowHelperAfterCatch+0x83 
002be058 003c0a3a 00000000 00000000 0233d174 clr!JIT_NewArr1+0x1af 
... removed some rows, lots of data ... 


OS Thread Id: 0x1214 (0) 
Child SP IP  Call Site 
002bdfd4 7554c41f [Frame: 002bdfd4] 
002be060 003c0a3a 
... removed some rows, lots of data ... 


Error requesting GC Heap data 
Unable to determine bounds of gc heap 

Тогда позже я получаю это:

[6/16/2013 9:54:05 PM] CLR Exception Type - '' 
[6/16/2013 9:54:05 PM] First chance exception - 0xe0434352 caused by thread with System ID: 4628 
[6/16/2013 9:54:05 PM] Unable to determine CLR exception type 

Тогда, наконец, я получаю

[6/16/2013 9:54:05 PM] CLR Exception Type - '' 
[6/16/2013 9:54:05 PM] C:\Windows\Microsoft.NET\Framework\v4.0.30319\diasymreader.dll loaded at 0x615c0000 
[6/16/2013 9:54:13 PM] Second chance exception - 0xe0434352 caused by thread with System ID: 4628 

Похоже, это может быть способный получить адрес объекта исключения, равен 0, поэтому, когда скрипт вызывает DumpObject, он не может найти информацию об исключении.

Как я прочитал эти записи журнала, я получаю собственное исключение из первого шанса из malloc или что-то еще, а затем за исключением исключения CLR для исключения OutOfMemoryException. Я пытаюсь выяснить, что второе из первого случая исключения, мой код выглядит следующим образом:

private void OnGrowMemoryCommand(int growMemorySize) 
{ 
    try 
    { 
     _heldMemoryChunks.Add(new byte[growMemorySize * 1024 * 1024]); 
    } 
    catch (Exception) 
    { 
     throw; 
    } 
    TotalMemorySize += growMemorySize; 
} 

Этот код генерируется из команды на кнопке WPF. Из-за этого любые исключения, возникающие из этого кода, должны приводить к исключению TargetInvocationException, которое, по моему мнению, является вторым из исключения первого шанса. Затем, наконец, из блока throw это второе исключение, которое имеет тип TargetInvocationException.

Итак, я начинаю смотреть на файл дампа второго шанса. Я загрузить его в WinDbg, то следующие команды:

.symfix C:\symcache 
.loadby sos clr 
.reload 

!pe 
Exception object: 023caf9c 
Exception type: System.Reflection.TargetInvocationException 
Message:   Exception has been thrown by the target of an invocation. 
InnerException: System.OutOfMemoryException, Use !PrintException 023c9928 to see more. 

я вижу, что мои предположения выше подтверждается тем фактом, что второй шанс исключением является TargetInvocationException, но почему не может DebugDiag получить CLR типы исключений? Для проверки работоспособности я пытаюсь провести сеанс отладки. Поэтому я запускаю приложение и присоединяюсь, затем я выдаю эти команды.

.symfix C:\symcache 
.loadby sos clr 
.reload 

!threads 
Failed to request ThreadStore 

!dumpheap 
The garbage collector data structures are not in a valid state for traversal. 
It is either in the "plan phase," where objects are being moved around, or 
we are at the initialization or shutdown of the gc heap. Commands related to 
displaying, finding or traversing objects as well as gc heap segments may not 
work properly. !dumpheap and !verifyheap may incorrectly complain of heap 
consistency errors. 
Error requesting GC Heap data 
Unable to build snapshot of the garbage collector state 

Это полностью закрытый. Поэтому я начинаю исследовать этот вопрос.

Этот URL предполагает, что это может быть несколько экземпляров CLR:

http://blogs.msdn.com/b/jjameson/archive/2011/01/11/issues-debugging-managed-code-in-windbg-with-sos-and-psscor2-e-g-quot-failed-to-request-threadstore-quot.aspx

Так что следующие команды:

.cordll 
CLR DLL status: Loaded DLL C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll 

Это странно для меня, я думал, что с 4,0 на этой mscorwks был брошен в пользу clr. Является ли mscordacwks 4,5?

Я выпустил эту команду:

lmvm mscordacwks 

Но CLR загружен:

lmvm clr 
start end  module name 
6a350000 6a9e2000 clr  (pdb symbols)   C:\symcache\clr.pdb\97FD69E1786F42F9A541C81D81AC96852\clr.pdb 
    Loaded symbol image file: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll 
    Image path: C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll 
    Image name: clr.dll 
    Timestamp:  Fri Mar 29 00:13:44 2013 (51553118) 
    CheckSum:   0069496E 
    ImageSize:  00692000 
    File version:  4.0.30319.18047 
    Product version: 4.0.30319.18047 
    File flags:  8 (Mask 3F) Private 
    File OS:   4 Unknown Win32 
    File type:  2.0 Dll 
    File date:  00000000.00000000 
    Translations:  0409.04b0 
    CompanyName:  Microsoft Corporation 
    ProductName:  Microsoft® .NET Framework 
    InternalName:  clr.dll 
    OriginalFilename: clr.dll 
    ProductVersion: 4.0.30319.18047 
    FileVersion:  4.0.30319.18047 built by: FX45RTMGDR 
    PrivateBuild:  DDBLD316 
    FileDescription: Microsoft .NET Runtime Common Language Runtime - WorkStation 
    LegalCopyright: © Microsoft Corporation. All rights reserved. 
    Comments:   Flavor=Retail 

Так что я не думаю, что у меня есть несколько Clrs загружены.

Таким образом, я предполагаю, что то же самое, что вызывает мои проблемы с отладкой в ​​реальном времени, приводит к тому, что я не запускаю первую проблему. Есть идеи?

+0

Правильный способ получения информации об этом виде исключений заключается в том, чтобы следовать этой статье, http://blogs.msdn.com/b/tom/archive/2008/05/19/asp-net-tips-what- to-gather-to-troubleshoot-part-5-outofmemoryexception.aspx Вы не должны пытаться получить дамп исключений при первой возможности. Кроме того, вам даже не нужно записывать дамп при исключении, если вы можете захватить висячие дампы, когда использование памяти слишком велико (> 1 ГБ). KB2020006 документирует общие причины таких проблем, поэтому вы можете начать с этого момента, http://support.microsoft.com/kb/2020006 –

+0

Похоже, вы настроили DebugDiag для обнаружения исключений * неуправляемого * исключения. 0xe06d7363 ('msc') - исключение C++, возможно std :: bad_alloc. 0xe0434352 ('ccr') - это основное исключение SEH для управляемых исключений. Это не оживает, пока вы не используете управляемый инструмент отладки, sos.dll получил управляемое исключение. –

+0

@ Lex Li, есть более чем один способ сделать это, и я не думаю, что тот, который вы предлагаете, подходит для меня. Метод требует изменения записи в реестре, которое я не хочу делать во всех ящиках.Кроме того, я не согласен с тем, что нет необходимости записывать дамп в исключении OOM, я согласен, что вы можете видеть проблемы до этого, но приятно знать, что происходит, когда происходит OOM. Наконец, я все еще не могу отлаживать живой экземпляр с windbg, который вызывает большую озабоченность, чем свалка. – taylorjonl

ответ

2

Я столкнулся с той же ошибкой на двух машинах. Оба были оснащены .NET 4.5, поэтому я думаю, что это причина, по которой это не сработало.

Это оказалось ошибкой в ​​сценариях DebugDiag. Он не может получить имя исключения CLR в одном из его скриптов. Однако эта проблема исправлена, так как каждое правило DebugDiag создает скрипт vbs, который можно изменить. Он использует те же самые команды, которые вы также можете использовать в WinDbg. Вот как это исправить:

  • Создайте правило DebugDiag с помощью графического интерфейса пользователя, как вы уже это делали.
  • Для каждого правила создается файл сценария vbs. Откройте его в текстовом редакторе под C:\Program Files\DebugDiag\Scripts\CrashRule_<rulename>.vbs
  • найти функцию GetCLRExceptionType
  • изменить его следующим образом:

    Function GetCLRExceptionType(ByVal ExceptionObjHexAddr, ByVal bInnerException) 
        Dim Output, Lines, i 
    
        If Debugger.IsClrExtensionMissing Then 
         WriteToLog "Unable to determine CLR exception type - extension dll could not be loaded." 
        Else 
         ' Output = Debugger.Execute("!DumpObj " & ExceptionObjHexAddr) ' Does not work in .NET 4.5 
         Output = Debugger.Execute("!pe") ' FIX .NET45 
    
         Lines = Split(Output, Chr(10)) 
         For i = 0 To UBound(Lines)  
          If bInnerException Then 
           If InStr(Lines(i), "_innerException") <> 0 Then 
            Tokens = Split(Lines(i), " ") 
            For j = 0 To UBound(Tokens) 
             If Len(Tokens(j)) = 8 Then        
              GetCLRExceptionType = GetCLRExceptionType(Tokens(j), False) 
              Exit For 
             End If 
            Next 
           End If 
          ElseIf Len(Lines(i)) >= 7 Then 
           If InStr(Lines(i), "Exception type:") = 1 Then ' FIX .NET45 
            GetCLRExceptionType = Trim(Mid(Lines(i), 16)) ' FIX .NET45 
            Exit For 
           End If 
          End If 
         Next 
    
         If GetCLRExceptionType = "" Then 
          If g_ClrExceptionTypeFailureLogCount < MAX_CLR_EXCEPTION_TYPE_FAILURE_LOG_ENTRIES Then 
           g_ClrExceptionTypeFailureLogCount = g_ClrExceptionTypeFailureLogCount + 1 
    
           WriteToLog "Unable to determine CLR exception type" & vbcrlf & _ 
            "ExceptionObjHexAddr = " & ExceptionObjHexAddr & vbcrlf & _ 
            "bInnerException = " & bInnerException & vbcrlf & _ 
            "DumpObject Output = " & Output & vbcrlf & _ 
            Debugger.Execute("kb100") & vbcrlf & _ 
            Debugger.Execute("!clrstack") & vbcrlf & _ 
            Debugger.Execute("!dso") 
          End If 
         End If 
        End If 
    End Function 
    

По умолчанию !DumpObj используется для вывода содержимого объекта исключения. Однако что-то изменилось в .NET 4.5 и, очевидно, тип исключения больше не может быть извлечен. Вместо этого поместите команду !pe и проанализируйте тип исключения из его результата.

Для того, чтобы сделать работу !pe, вам необходимо сделать .loadby sos clr. Я добавил его к югу Debugger_OnLoadModule:

Sub Debugger_OnLoadModule(ByVal NewModule) 
    WriteToLog NewModule.ImageName & " loaded at " & Debugger.GetAs32BitHexString(NewModule.Base) 
    Select Case UCase(NewModule.ModuleName) 
     Case "MSCORWKS", "MSCORSVR", "CLR", "CORECLR" 
      UpdateDeferredManagedBreakpoints 
    End Select 

    Debugger.Execute(".loadby sos clr") 
End Sub 

После внесения изменений, нужно либо перезапустить processs или отключить/активировать правило для ее применения.

Также: имейте в виду, что если вы измените свое правило в графическом интерфейсе DebugDiag, изменения будут полностью перезаписаны.

+0

Отличный ответ! Работает на меня. В той же заметке - я только что обновился до DebugDiag 2.0, в котором я не сталкивался с этой проблемой –