2 // Mono Runtime gateway functions
7 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Runtime
.CompilerServices
;
32 using System
.Runtime
.InteropServices
;
36 #if MOBILE || XAMMAC_4_5
42 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
43 private static extern void mono_runtime_install_handlers ();
45 #if MOBILE || XAMMAC_4_5
50 static void InstallSignalHandlers ()
52 mono_runtime_install_handlers ();
55 #if MOBILE || XAMMAC_4_5
56 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
57 static extern void mono_runtime_cleanup_handlers ();
59 public static void RemoveSignalHandlers ()
61 mono_runtime_cleanup_handlers ();
65 // Should not be removed intended for external use
66 // Safe to be called using reflection
67 // Format is undefined only for use as a string for reporting
68 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
69 #if MOBILE || XAMMAC_4_5
74 static extern string GetDisplayName ();
76 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
77 static extern string GetNativeStackTrace (Exception exception
);
79 public static bool SetGCAllowSynchronousMajor (bool flag
)
85 static object exception_capture
= new object ();
87 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
88 static extern string ExceptionToState_internal (Exception exc
, out ulong portable_hash
, out ulong unportable_hash
);
90 static Tuple
<String
, ulong, ulong>
91 ExceptionToState (Exception exc
)
94 ulong unportable_hash
;
95 string payload_str
= ExceptionToState_internal (exc
, out portable_hash
, out unportable_hash
);
97 return new Tuple
<String
, ulong, ulong> (payload_str
, portable_hash
, unportable_hash
);
102 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
103 static extern void DisableMicrosoftTelemetry ();
105 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
106 static extern void EnableMicrosoftTelemetry_internal (IntPtr appBundleID
, IntPtr appSignature
, IntPtr appVersion
, IntPtr merpGUIPath
, IntPtr appPath
, IntPtr configDir
);
108 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
109 static extern void SendMicrosoftTelemetry_internal (IntPtr payload
, ulong portable_hash
, ulong unportable_hash
);
111 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
112 static extern void WriteStateToFile_internal (IntPtr payload
, ulong portable_hash
, ulong unportable_hash
);
115 WriteStateToFile (Exception exc
)
118 ulong unportable_hash
;
119 string payload_str
= ExceptionToState_internal (exc
, out portable_hash
, out unportable_hash
);
120 using (var payload_chars
= RuntimeMarshal
.MarshalString (payload_str
))
122 WriteStateToFile_internal (payload_chars
.Value
, portable_hash
, unportable_hash
);
126 static void SendMicrosoftTelemetry (string payload_str
, ulong portable_hash
, ulong unportable_hash
)
128 if (RuntimeInformation
.IsOSPlatform (OSPlatform
.OSX
)) {
129 using (var payload_chars
= RuntimeMarshal
.MarshalString (payload_str
))
131 SendMicrosoftTelemetry_internal (payload_chars
.Value
, portable_hash
, unportable_hash
);
134 throw new PlatformNotSupportedException("Merp support is currently only supported on OSX.");
140 // catch (Exception exc) {
141 // var monoType = Type.GetType ("Mono.Runtime", false);
142 // var m = monoType.GetMethod("SendExceptionToTelemetry", BindingFlags.NonPublic | BindingFlags.Static);
143 // m.Invoke(null, new object[] { exc });
145 static void SendExceptionToTelemetry (Exception exc
)
148 ulong unportable_hash
;
149 lock (exception_capture
)
151 string payload_str
= ExceptionToState_internal (exc
, out portable_hash
, out unportable_hash
);
152 SendMicrosoftTelemetry (payload_str
, portable_hash
, unportable_hash
);
156 // All must be set except for configDir_str
157 static void EnableMicrosoftTelemetry (string appBundleID_str
, string appSignature_str
, string appVersion_str
, string merpGUIPath_str
, string unused
/* eventType_str */, string appPath_str
, string configDir_str
)
159 if (RuntimeInformation
.IsOSPlatform (OSPlatform
.OSX
)) {
160 using (var appBundleID_chars
= RuntimeMarshal
.MarshalString (appBundleID_str
))
161 using (var appSignature_chars
= RuntimeMarshal
.MarshalString (appSignature_str
))
162 using (var appVersion_chars
= RuntimeMarshal
.MarshalString (appVersion_str
))
163 using (var merpGUIPath_chars
= RuntimeMarshal
.MarshalString (merpGUIPath_str
))
164 using (var appPath_chars
= RuntimeMarshal
.MarshalString (appPath_str
))
165 using (var configDir_chars
= RuntimeMarshal
.MarshalString (configDir_str
))
167 EnableMicrosoftTelemetry_internal (appBundleID_chars
.Value
, appSignature_chars
.Value
, appVersion_chars
.Value
, merpGUIPath_chars
.Value
, appPath_chars
.Value
, configDir_chars
.Value
);
170 throw new PlatformNotSupportedException("Merp support is currently only supported on OSX.");
175 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
176 static extern string DumpStateSingle_internal (out ulong portable_hash
, out ulong unportable_hash
);
178 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
179 static extern string DumpStateTotal_internal (out ulong portable_hash
, out ulong unportable_hash
);
181 static Tuple
<String
, ulong, ulong>
185 ulong unportable_hash
;
186 string payload_str
= DumpStateSingle_internal (out portable_hash
, out unportable_hash
);
188 return new Tuple
<String
, ulong, ulong> (payload_str
, portable_hash
, unportable_hash
);
191 static Tuple
<String
, ulong, ulong>
195 ulong unportable_hash
;
196 string payload_str
= DumpStateTotal_internal (out portable_hash
, out unportable_hash
);
198 return new Tuple
<String
, ulong, ulong> (payload_str
, portable_hash
, unportable_hash
);
201 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
202 static extern void RegisterReportingForAllNativeLibs_internal ();
204 static void RegisterReportingForAllNativeLibs ()
206 RegisterReportingForAllNativeLibs_internal ();
209 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
210 static extern void RegisterReportingForNativeLib_internal (IntPtr modulePathSuffix
, IntPtr moduleName
);
212 static void RegisterReportingForNativeLib (string modulePathSuffix_str
, string moduleName_str
)
214 using (var modulePathSuffix_chars
= RuntimeMarshal
.MarshalString (modulePathSuffix_str
))
215 using (var moduleName_chars
= RuntimeMarshal
.MarshalString (moduleName_str
))
217 RegisterReportingForNativeLib_internal (modulePathSuffix_chars
.Value
, moduleName_chars
.Value
);
221 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
222 static extern void EnableCrashReportLog_internal (IntPtr directory
);
224 static void EnableCrashReportLog (string directory_str
)
226 using (var directory_chars
= RuntimeMarshal
.MarshalString (directory_str
))
228 EnableCrashReportLog_internal (directory_chars
.Value
);
232 enum CrashReportLogLevel
: int {
235 MonoSummarySuspendHandshake
,
236 MonoSummaryUnmanagedStacks
,
237 MonoSummaryManagedStacks
,
238 MonoSummaryStateWriter
,
239 MonoSummaryStateWriterDone
,
240 MonoSummaryMerpWriter
,
241 MonoSummaryMerpInvoke
,
245 MonoSummaryDoubleFault
248 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
249 static extern int CheckCrashReportLog_internal (IntPtr directory
, bool clear
);
251 static CrashReportLogLevel
CheckCrashReportLog (string directory_str
, bool clear
)
253 using (var directory_chars
= RuntimeMarshal
.MarshalString (directory_str
))
255 return (CrashReportLogLevel
) CheckCrashReportLog_internal (directory_chars
.Value
, clear
);
259 static string get_breadcrumb_value (string file_prefix
, string directory_str
, bool clear
)
261 var allfiles
= Directory
.GetFiles (directory_str
, $"{file_prefix}_*" );
262 if (allfiles
.Length
== 0)
265 if (allfiles
.Length
> 1) {
266 // it's impossible to tell which breadcrumb is the last one (let's not trust filesystem timestamps)
267 // delete the multiple files so at least next crash can make sense
269 Array
.ForEach (allfiles
, f
=> File
.Delete (f
) );
270 } catch (Exception
) { }
276 File
.Delete (allfiles
[0]);
278 var filename
= Path
.GetFileName (allfiles
[0]);
279 return filename
.Substring (file_prefix
.Length
+ 1);
282 static long CheckCrashReportHash (string directory_str
, bool clear
)
284 var value = get_breadcrumb_value ("crash_hash", directory_str
, clear
);
285 if (value == string.Empty
)
288 return Convert
.ToInt64 (value, 16);
291 static string CheckCrashReportReason (string directory_str
, bool clear
)
293 return get_breadcrumb_value ("crash_reason", directory_str
, clear
);
296 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
297 static extern void AnnotateMicrosoftTelemetry_internal (IntPtr key
, IntPtr val
);
299 static void AnnotateMicrosoftTelemetry (string key
, string val
)
301 using (var key_chars
= RuntimeMarshal
.MarshalString (key
))
302 using (var val_chars
= RuntimeMarshal
.MarshalString (val
))
304 AnnotateMicrosoftTelemetry_internal (key_chars
.Value
, val_chars
.Value
);