Elevado consumo de memoria del proceso DbgHost.exe de DebugDiag

En algunos entornos, cuando se utiliza Debug Diagnostics para monitorizar excepciones de .NET, se dispara el consumo de memoria del proceso DbgHost.exe. El motivo de la pérdida de memoria es un bug en la extensión del depurador SOS.dll que se instala con el Framework .NET, concretamente al ejecutar el comando !DumpObj de dicha extensión.

Para solucionar este problema, podemos modificar el fichero de script que genera DebugDiag de forma que no utilice el comando !DumpObj sino !PrintException que no adolece del mismo problema. Por lo tanto, los pasos a seguir son los siguientes:

1) Borrar todas las reglas de DebugDiag existentes.

2) Volver a crear las regla para monitorizar excepciones .NET, pero sin activarlaal final del proceso.

3) Ir a la carpeta de scripts de DebugDiag, la ruta podría ser algo parecido a esto: C:\Program Files\DebugDiag\scripts

4) En esa carpeta encontraréis algún fichero cuyo nombre empiece por CrashRule_...*.vbs con el nombre de la regla que habéis creado. Abrid este fichero con algún editor.

5) Buscad la función GetCLRExceptionType, que tendrá un aspecto parecido a este:

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)

Lines = Split(Output, Chr(10))

For i = 0 To UBound(Lines)

If bInnerException Then

If Len(Lines(i) >= 68) Then

If InStr(Lines(i), "_innerException") <> 0 Then

GetCLRExceptionType = GetCLRExceptionType("0x" & Mid(Lines(i), _

60, 8), False)

Exit For

End If

End If

ElseIf Len(Lines(i)) >= 7 Then

If InStr(Lines(i), "Name: ") = 1 Then

GetCLRExceptionType = Mid(Lines(i), 7)

Exit For

End If

End If

Next

End If

End Function

6) Eliminad dicha función y sustituidla por esta otra:

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("!PrintException")

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

GetCLRExceptionType = Mid(Lines(i), 17)

WriteToLog(Lines(i))

Exit For

End If

End If

Next

End If

End Function

7) Guardad los cambios en el fichero CrashRule_...*.vbs volved a DebugDiag y en la pestaña Rules y activad la regla.

clip_image002

 

Realizando estos pases resolveréis el problema de consumo de memoria en DbgHost.exe.

Hasta el próximo post.

- Daniel Mossberg