@ -8,9 +8,13 @@
@@ -8,9 +8,13 @@
using System ;
using System.Collections.Generic ;
using System.Data.SQLite ;
using System.Diagnostics ;
using System.Globalization ;
using System.IO ;
using System.Reflection ;
using System.Runtime.InteropServices ;
using System.Runtime.Serialization ;
using System.Security ;
using System.Text ;
using System.Threading ;
@ -288,11 +292,11 @@ namespace ICSharpCode.UsageDataCollector
@@ -288,11 +292,11 @@ namespace ICSharpCode.UsageDataCollector
if ( exception = = null )
throw new ArgumentNullException ( "exception" ) ;
string exceptionType = GetTypeName ( exception ) ;
string stacktrace = exception . StackTrace ;
string stacktrace = GetStackTrace ( exception ) ;
while ( exception . InnerException ! = null ) {
exception = exception . InnerException ;
stacktrace = exception . StackTrace + Environment . NewLine
stacktrace = GetStackTrace ( exception ) + Environment . NewLine
+ "-- continuing with outer exception (" + exceptionType + ") --" + Environment . NewLine
+ stacktrace ;
exceptionType = GetTypeName ( exception ) ;
@ -309,6 +313,84 @@ namespace ICSharpCode.UsageDataCollector
@@ -309,6 +313,84 @@ namespace ICSharpCode.UsageDataCollector
return type ;
}
static string GetStackTrace ( Exception exception )
{
// Output stacktrace in custom format (very similar to Exception.StackTrace property on English systems).
// Include filenames where available, but no paths.
StackTrace stackTrace = new StackTrace ( exception , true ) ;
StringBuilder b = new StringBuilder ( ) ;
for ( int i = 0 ; i < stackTrace . FrameCount ; i + + ) {
StackFrame frame = stackTrace . GetFrame ( i ) ;
MethodBase method = frame . GetMethod ( ) ;
if ( method = = null )
continue ;
if ( b . Length > 0 )
b . AppendLine ( ) ;
b . Append ( " at " ) ;
Type declaringType = method . DeclaringType ;
if ( declaringType ! = null ) {
b . Append ( declaringType . FullName . Replace ( '+' , '.' ) ) ;
b . Append ( '.' ) ;
}
b . Append ( method . Name ) ;
// output type parameters, if any
if ( ( method is MethodInfo ) & & ( ( MethodInfo ) method ) . IsGenericMethod ) {
Type [ ] genericArguments = ( ( MethodInfo ) method ) . GetGenericArguments ( ) ;
b . Append ( '[' ) ;
for ( int j = 0 ; j < genericArguments . Length ; j + + ) {
if ( j > 0 )
b . Append ( ',' ) ;
b . Append ( genericArguments [ j ] . Name ) ;
}
b . Append ( ']' ) ;
}
// output parameters, if any
b . Append ( '(' ) ;
ParameterInfo [ ] parameters = method . GetParameters ( ) ;
for ( int j = 0 ; j < parameters . Length ; j + + ) {
if ( j > 0 )
b . Append ( ", " ) ;
if ( parameters [ j ] . ParameterType ! = null ) {
b . Append ( parameters [ j ] . ParameterType . Name ) ;
} else {
b . Append ( '?' ) ;
}
if ( ! string . IsNullOrEmpty ( parameters [ j ] . Name ) ) {
b . Append ( ' ' ) ;
b . Append ( parameters [ j ] . Name ) ;
}
}
b . Append ( ')' ) ;
// source location
if ( frame . GetILOffset ( ) > = 0 ) {
string filename = null ;
try {
string fullpath = frame . GetFileName ( ) ;
if ( fullpath ! = null )
filename = Path . GetFileName ( fullpath ) ;
} catch ( SecurityException ) {
// StackFrame.GetFileName requires PathDiscovery permission
} catch ( ArgumentException ) {
// Path.GetFileName might throw on paths with invalid chars
}
b . Append ( " in " ) ;
if ( filename ! = null ) {
b . Append ( filename ) ;
b . Append ( ":line " ) ;
b . Append ( frame . GetFileLineNumber ( ) ) ;
} else {
b . Append ( "offset " ) ;
b . Append ( frame . GetILOffset ( ) ) ;
}
}
}
return b . ToString ( ) ;
}
/// <summary>
/// Adds an exception report to the session.
/// </summary>