-
-
Save joeisapro/829665aa232029b48e16 to your computer and use it in GitHub Desktop.
Xamarin/Crashlytics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Setup | |
{ | |
private enum Signal | |
{ | |
SIGBUS = 10, | |
SIGSEGV | |
} | |
private static string Library = ""; | |
[DllImport("libc")] | |
private static extern int sigaction(Setup.Signal sig, IntPtr act, IntPtr oact); | |
[DllImport(Constants.ObjectiveCLibrary, EntryPoint = "objc_msgSend")] | |
private static extern void void_objc_msgSend(IntPtr receiver, IntPtr selector); | |
public static void EnableCrashReporting(Action crashReportingDelegate, string library) | |
{ | |
Library = library; | |
IntPtr sigbus = Marshal.AllocHGlobal(512); | |
IntPtr sigsev = Marshal.AllocHGlobal(512); | |
//store handlers | |
Setup.sigaction(Setup.Signal.SIGBUS, IntPtr.Zero, sigbus); | |
Setup.sigaction(Setup.Signal.SIGSEGV, IntPtr.Zero, sigsev); | |
//setup crash reporting | |
crashReportingDelegate(); | |
//restore handlers | |
Setup.sigaction(Setup.Signal.SIGBUS, sigbus, IntPtr.Zero); | |
Setup.sigaction(Setup.Signal.SIGSEGV, sigsev, IntPtr.Zero); | |
Marshal.FreeHGlobal(sigbus); | |
Marshal.FreeHGlobal(sigsev); | |
} | |
public static void ThrowExceptionAsNative(Exception exception) | |
{ | |
Setup.ConvertToNativeExceptionAndRaise(exception); | |
} | |
public static void ThrowExceptionAsNative(object exception) | |
{ | |
Setup.ConvertToNativeExceptionAndRaise(exception); | |
} | |
public static void CaptureManagedInfo(object exception) | |
{ | |
Crashlytics.SharedInstance.SetObjectValue(new NSString(Constants.Version), "monotouch version"); | |
Exception ex = exception as Exception; | |
if (ex != null) | |
{ | |
Crashlytics.SharedInstance.SetObjectValue(new NSString(ex.StackTrace), "unhandled exception stack trace"); | |
Crashlytics.SharedInstance.SetObjectValue(new NSString(ex.Message), "unhandled exception message"); | |
Crashlytics.SharedInstance.SetObjectValue(new NSString(ex.GetType().FullName), "unhandled exception"); | |
} | |
} | |
public static void CaptureStackFrames(object exception) | |
{ | |
var frames = new List<CLSStackFrame>(); | |
Exception ex = exception as Exception; | |
Action<StackTrace> frameWalker = (st) => | |
{ | |
for (int i = 0; i < st.FrameCount; i++) | |
{ | |
StackFrame sf = st.GetFrame(i); | |
frames.Add(new CLSStackFrame() | |
{ | |
FileName = sf.GetFileName() ?? sf.GetMethod().DeclaringType.Name + ".cs", | |
LineNumber = (uint)sf.GetFileLineNumber(), | |
Library = Library, | |
Symbol = sf.GetMethod().ToString() | |
}); | |
} | |
}; | |
if (ex != null) | |
{ | |
//get traces from excetion dispath info - their are not included in StackTrace on mono | |
StackTrace[] traces = null; | |
var fi = typeof(Exception).GetField("captured_traces", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); | |
if (fi != null) | |
traces = fi.GetValue(ex) as StackTrace[]; | |
if (traces != null) | |
foreach (var st in traces) | |
frameWalker(st); | |
frameWalker(new StackTrace(ex, true)); | |
Crashlytics.SharedInstance.RecordCustomExceptionName(ex.GetType().Name, ex.Message, frames.Cast<NSObject>().ToArray()); | |
} | |
} | |
private static void ConvertToNativeExceptionAndRaise(object e) | |
{ | |
string name = "Managed Exception"; | |
string reason = e.ToString(); | |
Exception ex = e as Exception; | |
if (ex != null) | |
{ | |
string file = "Unknown file"; | |
string line = "???"; | |
try | |
{ | |
if (!string.IsNullOrEmpty(reason)) | |
{ | |
string buf = reason; | |
buf = buf.Replace(ex.Message, ""); | |
buf = buf.Replace(ex.GetType().FullName, ""); | |
var pos = buf.IndexOf(" in "); | |
var pos2 = buf.IndexOf(".cs", pos); | |
file = buf.Substring(pos + 4, pos2 + 3 - (pos + 4)); | |
file = Path.GetFileName(file); | |
int i = pos2 + 4; | |
string line2 = ""; | |
char tmp = reason[i]; | |
while ("0123456789".Contains(buf[i].ToString()) && i < buf.Length) | |
line2 += buf[i++]; | |
line = line2; | |
} | |
} | |
catch | |
{ | |
} | |
name = string.Format("{0}: {1} - {2} line {3}", ex.GetType().FullName, ex.Message, file, line); | |
} | |
name = name.Replace("%", "%%"); | |
reason = reason.Replace("%", "%%"); | |
NSException nsex = new NSException(name, reason, null); | |
Selector selector = new Selector("raise"); | |
void_objc_msgSend(nsex.Handle, selector.Handle); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment