我正在分析遗留应用程序中的错误,因为我将其清理并进行改进。我有一些堆栈跟踪记录到数据库,但有一个限制(VARCHAR2(1000))存储多少,并且错误发生在System.Data深层......
at System.Data.OracleClient.OracleConnection.CheckError(OciErrorHandle errorHandle, Int32 rc)
at System.Data.OracleClient.OracleCommand.Execute(OciStatementHandle statementHandle, CommandBehavior behavior, Boolean needRowid, OciRowidDescriptor& rowidDescriptor, ArrayList& resultParameterOrdinals)
at System.Data.OracleClient.OracleCommand.Execute(OciStatementHandle statementHandle, CommandBehavior behavior, ArrayList& resultParameterOrdinals)
at System.Data.OracleClient.OracleCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OracleClient.OracleCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
我不关心所有这些 - 我只需要找到哪些C#代码和哪个proc产生错误。因此,我可以找出根本原因,将代码重构为质量并改进每个模块,因为我点击了最低挂起最错误的代码。
在我去写东西之前,有人会有一些东西会限制堆栈跟踪到某些程序集,所以我可以找到根本原因吗?或者是堆栈跟踪解析器或现成的东西,我可以用来在记录错误之前删除我不感兴趣的东西?
答案 0 :(得分:2)
你很幸运 - 有人读过你的帖子!我想通过将我的错误重新格式化为这样的东西,至少从史蒂文金小说的阅读中拯救了我的眼睛:
(< pre>不尊重我的tabstops,所以它在现实生活中看起来更好)
System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
FUNCTION FILE LINE
CoCreateInstance (no .PDB)
CreateWithoutLicense (no .PDB)
CreateWithLicense (no .PDB)
CreateInstanceCore (no .PDB)
CreateInstance (no .PDB)
GetOcxCreate (no .PDB)
TransitionUpTo (no .PDB)
CreateHandle (no .PDB)
CreateControl (no .PDB)
CreateControl (no .PDB)
EndInit (no .PDB)
InitializeComponent frmGetSig.Designer.vb 187
ctor frmGetSig.vb 264
btnSign_Click ucSignCapture_v2.vb 306
使用此代码:
Public Shared Function ReduceError(ByVal stExceptionToString As String) As String
Try
''// split into message and stack trace items
Dim stMainSplit() As String = Split(stExceptionToString, vbCrLf & " at ")
If UBound(stMainSplit) = 0 Then
Return stExceptionToString
End If
''// add the message
Dim stResults As String = stMainSplit(0) & vbCrLf
Dim bLastWasInner As Boolean
''// Headings, if there is a stack trace
If UBound(stMainSplit) > 0 Then
stResults &= "FUNCTION" & vbTab & "FILE" & vbTab & "LINE" & vbCrLf
End If
''// reduce the stack trace
For i As Integer = 1 To UBound(stMainSplit)
Dim st As String = stMainSplit(i)
''// skip the line following inner exception in stack trace
If Not bLastWasInner Then
''// split the sub from line # info
Dim stln() As String = Split(st, ")")
If UBound(stln) = 1 Then
''// first put the sub on there
Dim stsub As String = Mid(stln(0), 1, InStrRev(stln(0), "(") - 1)
If InStr(stsub, ".") <> 0 Then
stsub = Mid(stsub, InStrRev(stsub, ".") + 1)
End If
stResults &= stsub & vbTab
''// Now if there is file/line # info, add that.
Dim stFile As String = "(no .PDB)"
If 0 <> InStr(stln(1), "\") Then '' " //good grief SOF learn vb ;-)
stFile = Replace(Mid(stln(1), InStrRev(stln(1), "\") + 1), ":line ", vbTab) '' "
''// take off CR and 'inner exception..." text
If InStr(stFile, vbCrLf) > 1 Then
stFile = Mid(stFile, 1, InStr(stFile, vbCrLf) - 1)
End If
End If
stResults &= stFile & vbCrLf
Else
stResults &= "Line split by ) has no (" & vbTab & vbCrLf
End If
End If
If 0 <> InStr(st, "End of inner exception stack trace") Then
bLastWasInner = True
Else
bLastWasInner = False
End If
Next
Return stResults
Catch ex As Exception
''// might want to return orig error here as well..
Return "Error summarizing routine as error'd: " & ex.ToString
End Try
End Function
它放入我在文本框中使用的标签,如果你愿意,很容易改变;如果你不关心system.data行,你可以随时排除它们。为.net 1.1编写,应该转换为c#well。
答案 1 :(得分:1)
最简单的方法是增加限制。
亚军最简单的方法是修改日志记录,使其占用堆栈跟踪的最后1000个字符(如果它更长),而不是插入整个内容。任何其他解决方案还必须修改日志记录或作为MitM拦截和更改信息,然后再继续使用记录器。
您无法更改.NET生成堆栈跟踪文本的方式(例如忽略某些程序集),因此在记录之前这一切都归结为字符串操作。
答案 2 :(得分:0)
我最后只使用正则表达式删除了我不想要的行:
Trace = Regex.Replace(Trace
, "^.*" + FilterPattern + ".*$\n"
, string.Empty
, RegexOptions.Multiline | RegexOptions.IgnoreCase);