[build] Skips RemoteExecuted bases tests on monodroid
[mono-project.git] / mono / utils / mono-state.c
blobfa9bda235415d1bbcb8d18a358cca1e259fc22b3
1 /**
2 * \file
3 * Support for verbose unmanaged crash dumps
5 * Author:
6 * Alexander Kyte (alkyte@microsoft.com)
8 * (C) 2018 Microsoft, Inc.
11 #include <config.h>
12 #include <glib.h>
13 #include <mono/utils/json.h>
14 #include <mono/utils/mono-state.h>
15 #include <mono/metadata/object-internals.h>
17 #ifdef TARGET_OSX
19 extern GCStats mono_gc_stats;
21 // For AOT mode
22 #include <mono/mini/mini-runtime.h>
24 #ifdef TARGET_OSX
25 #include <mach/mach.h>
26 #include <mach/task_info.h>
27 #endif
29 #define MONO_MAX_SUMMARY_LEN 900
30 static JsonWriter writer;
31 static GString static_gstr;
32 static char output_dump_str [MONO_MAX_SUMMARY_LEN];
34 static void mono_json_writer_init_static (void) {
35 static_gstr.len = 0;
36 static_gstr.allocated_len = MONO_MAX_SUMMARY_LEN;
37 static_gstr.str = output_dump_str;
38 memset (output_dump_str, 0, sizeof (output_dump_str));
40 writer.indent = 0;
41 writer.text = &static_gstr;
44 static void
45 mono_native_state_add_ctx (JsonWriter *writer, MonoContext *ctx)
47 // Context
48 mono_json_writer_indent (writer);
49 mono_json_writer_object_key(writer, "ctx");
50 mono_json_writer_object_begin(writer);
52 mono_json_writer_indent (writer);
53 mono_json_writer_object_key(writer, "IP");
54 mono_json_writer_printf (writer, "\"%p\",\n", (gpointer) MONO_CONTEXT_GET_IP (ctx));
56 mono_json_writer_indent (writer);
57 mono_json_writer_object_key(writer, "SP");
58 mono_json_writer_printf (writer, "\"%p\",\n", (gpointer) MONO_CONTEXT_GET_SP (ctx));
60 mono_json_writer_indent (writer);
61 mono_json_writer_object_key(writer, "BP");
62 mono_json_writer_printf (writer, "\"%p\"\n", (gpointer) MONO_CONTEXT_GET_BP (ctx));
64 mono_json_writer_indent_pop (writer);
65 mono_json_writer_indent (writer);
66 mono_json_writer_object_end (writer);
67 mono_json_writer_printf (writer, ",\n");
70 static void
71 mono_native_state_add_frame (JsonWriter *writer, MonoFrameSummary *frame)
73 mono_json_writer_indent (writer);
74 mono_json_writer_object_begin(writer);
76 if (frame->is_managed) {
77 mono_json_writer_indent (writer);
78 mono_json_writer_object_key(writer, "is_managed");
79 mono_json_writer_printf (writer, "\"%s\",\n", frame->is_managed ? "true" : "false");
82 if (frame->unmanaged_data.is_trampoline) {
83 mono_json_writer_indent (writer);
84 mono_json_writer_object_key(writer, "is_trampoline");
85 mono_json_writer_printf (writer, "\"true\",");
88 if (frame->is_managed) {
89 mono_json_writer_indent (writer);
90 mono_json_writer_object_key(writer, "guid");
91 mono_json_writer_printf (writer, "\"%s\",\n", frame->managed_data.guid);
93 mono_json_writer_indent (writer);
94 mono_json_writer_object_key(writer, "token");
95 mono_json_writer_printf (writer, "\"0x%05x\",\n", frame->managed_data.token);
97 mono_json_writer_indent (writer);
98 mono_json_writer_object_key(writer, "native_offset");
99 mono_json_writer_printf (writer, "\"0x%x\",\n", frame->managed_data.native_offset);
101 mono_json_writer_indent (writer);
102 mono_json_writer_object_key(writer, "il_offset");
103 mono_json_writer_printf (writer, "\"0x%05x\"\n", frame->managed_data.il_offset);
105 } else {
106 mono_json_writer_indent (writer);
107 mono_json_writer_object_key(writer, "native_address");
108 if (frame->unmanaged_data.ip)
109 mono_json_writer_printf (writer, "\"%p\"", (void *) frame->unmanaged_data.ip);
110 else
111 mono_json_writer_printf (writer, "\"outside mono-sgen\"");
113 if (frame->unmanaged_data.has_name) {
114 mono_json_writer_printf (writer, ",\n");
116 mono_json_writer_indent (writer);
117 mono_json_writer_object_key(writer, "unmanaged_name");
118 mono_json_writer_printf (writer, "\"%s\"\n", frame->str_descr);
119 } else {
120 mono_json_writer_printf (writer, "\n");
124 mono_json_writer_indent_pop (writer);
125 mono_json_writer_indent (writer);
126 mono_json_writer_object_end (writer);
129 static void
130 mono_native_state_add_frames (JsonWriter *writer, int num_frames, MonoFrameSummary *frames, const char *label)
132 mono_json_writer_indent (writer);
133 mono_json_writer_object_key(writer, label);
135 mono_json_writer_array_begin (writer);
137 mono_native_state_add_frame (writer, &frames [0]);
138 for (int i = 1; i < num_frames; ++i) {
139 mono_json_writer_printf (writer, ",\n");
140 mono_native_state_add_frame (writer, &frames [i]);
142 mono_json_writer_printf (writer, "\n");
144 mono_json_writer_indent_pop (writer);
145 mono_json_writer_indent (writer);
146 mono_json_writer_array_end (writer);
150 static void
151 mono_native_state_add_thread (JsonWriter *writer, MonoThreadSummary *thread, MonoContext *ctx)
153 static gboolean not_first_thread;
155 if (not_first_thread) {
156 mono_json_writer_printf (writer, ",\n");
157 } else {
158 not_first_thread = TRUE;
161 mono_json_writer_indent (writer);
162 mono_json_writer_object_begin(writer);
164 mono_json_writer_indent (writer);
165 mono_json_writer_object_key(writer, "is_managed");
166 mono_json_writer_printf (writer, "%s,\n", thread->is_managed ? "true" : "false");
168 mono_json_writer_indent (writer);
169 mono_json_writer_object_key(writer, "managed_thread_ptr");
170 mono_json_writer_printf (writer, "\"0x%x\",\n", (gpointer) thread->managed_thread_ptr);
172 mono_json_writer_indent (writer);
173 mono_json_writer_object_key(writer, "thread_info_addr");
174 mono_json_writer_printf (writer, "\"0x%x\",\n", (gpointer) thread->info_addr);
176 if (thread->name) {
177 mono_json_writer_indent (writer);
178 mono_json_writer_object_key(writer, "thread_name");
179 mono_json_writer_printf (writer, "\"%s\",\n", thread->name);
182 mono_json_writer_indent (writer);
183 mono_json_writer_object_key(writer, "native_thread_id");
184 mono_json_writer_printf (writer, "\"0x%x\",\n", (gpointer) thread->native_thread_id);
186 mono_native_state_add_ctx (writer, ctx);
188 if (thread->num_managed_frames > 0) {
189 mono_native_state_add_frames (writer, thread->num_managed_frames, thread->managed_frames, "managed_frames");
191 if (thread->num_unmanaged_frames > 0) {
192 if (thread->num_managed_frames > 0)
193 mono_json_writer_printf (writer, ",\n");
194 mono_native_state_add_frames (writer, thread->num_unmanaged_frames, thread->unmanaged_frames, "unmanaged_frames");
196 mono_json_writer_printf (writer, "\n");
198 mono_json_writer_indent (writer);
199 mono_json_writer_object_end (writer);
202 static void
203 mono_native_state_add_ee_info (JsonWriter *writer)
205 // FIXME: setup callbacks to enable
206 /*const char *aot_mode;*/
207 /*MonoAotMode mono_aot_mode = mono_jit_get_aot_mode ();*/
208 /*switch (mono_aot_mode) {*/
209 /*case MONO_AOT_MODE_NONE:*/
210 /*aot_mode = "none";*/
211 /*break;*/
212 /*case MONO_AOT_MODE_NORMAL:*/
213 /*aot_mode = "normal";*/
214 /*break;*/
215 /*case MONO_AOT_MODE_HYBRID:*/
216 /*aot_mode = "hybrid";*/
217 /*break;*/
218 /*case MONO_AOT_MODE_FULL:*/
219 /*aot_mode = "full";*/
220 /*break;*/
221 /*case MONO_AOT_MODE_LLVMONLY:*/
222 /*aot_mode = "llvmonly";*/
223 /*break;*/
224 /*case MONO_AOT_MODE_INTERP:*/
225 /*aot_mode = "interp";*/
226 /*break;*/
227 /*case MONO_AOT_MODE_INTERP_LLVMONLY:*/
228 /*aot_mode = "interp_llvmonly";*/
229 /*break;*/
230 /*default:*/
231 /*aot_mode = "error";*/
232 /*}*/
234 mono_json_writer_indent (writer);
235 mono_json_writer_object_key(writer, "execution_context");
236 mono_json_writer_object_begin(writer);
238 /*mono_json_writer_indent (writer);*/
239 /*mono_json_writer_object_key(writer, "aot_mode");*/
240 /*mono_json_writer_printf (writer, "\"%s\",\n", aot_mode);*/
242 /*mono_json_writer_indent (writer);*/
243 /*mono_json_writer_object_key(writer, "mono_use_llvm");*/
244 /*mono_json_writer_printf (writer, "\"%s\",\n", mono_use_llvm ? "true" : "false");*/
246 mono_json_writer_indent (writer);
247 mono_json_writer_object_key(writer, "coop-enabled");
248 mono_json_writer_printf (writer, "\"%s\"\n", mono_threads_is_cooperative_suspension_enabled () ? "true" : "false");
250 mono_json_writer_indent_pop (writer);
251 mono_json_writer_indent (writer);
252 mono_json_writer_object_end (writer);
253 mono_json_writer_printf (writer, ",\n");
256 // Taken from driver.c
257 #if defined(MONO_ARCH_ARCHITECTURE)
258 /* Redefine MONO_ARCHITECTURE to include more information */
259 #undef MONO_ARCHITECTURE
260 #define MONO_ARCHITECTURE MONO_ARCH_ARCHITECTURE
261 #endif
263 static void
264 mono_native_state_add_version (JsonWriter *writer)
266 mono_json_writer_indent (writer);
267 mono_json_writer_object_key(writer, "configuration");
268 mono_json_writer_object_begin(writer);
270 char *build = mono_get_runtime_callbacks ()->get_runtime_build_info ();
271 mono_json_writer_indent (writer);
272 mono_json_writer_object_key(writer, "version");
273 mono_json_writer_printf (writer, "\"%s\",\n", build);
275 mono_json_writer_indent (writer);
276 mono_json_writer_object_key(writer, "tlc");
277 #ifdef HAVE_KW_THREAD
278 mono_json_writer_printf (writer, "\"__thread\",\n");
279 #else
280 mono_json_writer_printf (writer, "\"normal\",\n");
281 #endif /* HAVE_KW_THREAD */
283 mono_json_writer_indent (writer);
284 mono_json_writer_object_key(writer, "sigsgev");
285 #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
286 mono_json_writer_printf (writer, "\"altstack\",\n");
287 #else
288 mono_json_writer_printf (writer, "\"normal\",\n");
289 #endif
291 mono_json_writer_indent (writer);
292 mono_json_writer_object_key(writer, "notifications");
293 #ifdef HAVE_EPOLL
294 mono_json_writer_printf (writer, "\"epoll\",\n");
295 #elif defined(HAVE_KQUEUE)
296 mono_json_writer_printf (writer, "\"kqueue\",\n");
297 #else
298 mono_json_writer_printf (writer, "\"thread+polling\",\n");
299 #endif
301 mono_json_writer_indent (writer);
302 mono_json_writer_object_key(writer, "architecture");
303 mono_json_writer_printf (writer, "\"%s\",\n", MONO_ARCHITECTURE);
305 mono_json_writer_indent (writer);
306 mono_json_writer_object_key(writer, "disabled_features");
307 mono_json_writer_printf (writer, "\"%s\",\n", DISABLED_FEATURES);
309 mono_json_writer_indent (writer);
310 mono_json_writer_object_key(writer, "smallconfig");
311 #ifdef MONO_SMALL_CONFIG
312 mono_json_writer_printf (writer, "\"enabled\",\n");
313 #else
314 mono_json_writer_printf (writer, "\"disabled\",\n");
315 #endif
317 mono_json_writer_indent (writer);
318 mono_json_writer_object_key(writer, "bigarrays");
319 #ifdef MONO_BIG_ARRAYS
320 mono_json_writer_printf (writer, "\"enabled\",\n");
321 #else
322 mono_json_writer_printf (writer, "\"disabled\",\n");
323 #endif
325 mono_json_writer_indent (writer);
326 mono_json_writer_object_key(writer, "softdebug");
327 #if !defined(DISABLE_SDB)
328 mono_json_writer_printf (writer, "\"enabled\",\n");
329 #else
330 mono_json_writer_printf (writer, "\"disabled\",\n");
331 #endif
333 mono_json_writer_indent (writer);
334 mono_json_writer_object_key(writer, "interpreter");
335 #ifndef DISABLE_INTERPRETER
336 mono_json_writer_printf (writer, "\"enabled\",\n");
337 #else
338 mono_json_writer_printf (writer, "\"disabled\",\n");
339 #endif
341 mono_json_writer_indent (writer);
342 mono_json_writer_object_key(writer, "llvm_support");
343 #ifdef MONO_ARCH_LLVM_SUPPORTED
344 #ifdef ENABLE_LLVM
345 mono_json_writer_printf (writer, "\"%s\"\n", LLVM_VERSION);
346 #else
347 mono_json_writer_printf (writer, "\"disabled\"\n");
348 #endif
349 #endif
351 mono_json_writer_indent_pop (writer);
352 mono_json_writer_indent (writer);
353 mono_json_writer_object_end (writer);
354 mono_json_writer_printf (writer, ",\n");
357 static void
358 mono_native_state_add_memory (JsonWriter *writer)
360 mono_json_writer_indent (writer);
361 mono_json_writer_object_key(writer, "memory");
362 mono_json_writer_object_begin(writer);
364 #ifdef TARGET_OSX
365 struct task_basic_info t_info;
366 memset (&t_info, 0, sizeof (t_info));
367 mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT;
368 task_name_t task = mach_task_self ();
369 task_info(task, TASK_BASIC_INFO, (task_info_t) &t_info, &t_info_count);
371 mono_json_writer_indent (writer);
372 mono_json_writer_object_key(writer, "Resident Size");
373 mono_json_writer_printf (writer, "\"%lu\",\n", t_info.resident_size);
375 mono_json_writer_indent (writer);
376 mono_json_writer_object_key(writer, "Virtual Size");
377 mono_json_writer_printf (writer, "\"%lu\",\n", t_info.virtual_size);
378 #endif
380 GCStats stats;
381 memcpy (&stats, &mono_gc_stats, sizeof (GCStats));
383 mono_json_writer_indent (writer);
384 mono_json_writer_object_key(writer, "minor_gc_time");
385 mono_json_writer_printf (writer, "\"%lu\",\n", stats.minor_gc_time);
387 mono_json_writer_indent (writer);
388 mono_json_writer_object_key(writer, "major_gc_time");
389 mono_json_writer_printf (writer, "\"%lu\",\n", stats.major_gc_time);
391 mono_json_writer_indent (writer);
392 mono_json_writer_object_key(writer, "minor_gc_count");
393 mono_json_writer_printf (writer, "\"%lu\",\n", stats.minor_gc_count);
395 mono_json_writer_indent (writer);
396 mono_json_writer_object_key(writer, "major_gc_count");
397 mono_json_writer_printf (writer, "\"%lu\",\n", stats.major_gc_count);
399 mono_json_writer_indent (writer);
400 mono_json_writer_object_key(writer, "major_gc_time_concurrent");
401 mono_json_writer_printf (writer, "\"%lu\"\n", stats.major_gc_time_concurrent);
403 mono_json_writer_indent_pop (writer);
404 mono_json_writer_indent (writer);
405 mono_json_writer_object_end (writer);
406 mono_json_writer_printf (writer, ",\n");
409 static void
410 mono_native_state_add_prologue (JsonWriter *writer)
412 mono_json_writer_init (writer);
413 mono_json_writer_object_begin(writer);
415 mono_json_writer_indent (writer);
416 mono_json_writer_object_key(writer, "protocol_version");
417 mono_json_writer_printf (writer, "\"%s\",\n", MONO_NATIVE_STATE_PROTOCOL_VERSION);
419 mono_native_state_add_version (writer);
421 #ifndef MONO_PRIVATE_CRASHES
422 mono_native_state_add_ee_info (writer);
423 #endif
425 mono_native_state_add_memory (writer);
427 const char *assertion_msg = g_get_assertion_message ();
428 if (assertion_msg != NULL) {
429 mono_json_writer_indent (writer);
430 mono_json_writer_object_key(writer, "assertion_message");
432 char *pos;
433 if ((pos = strchr (assertion_msg, '\n')) != NULL)
434 *pos = '\0';
436 mono_json_writer_printf (writer, "\"%s\",\n", assertion_msg);
439 // Start threads array
440 mono_json_writer_indent (writer);
441 mono_json_writer_object_key(writer, "threads");
442 mono_json_writer_array_begin (writer);
445 static void
446 mono_native_state_add_epilogue (JsonWriter *writer)
448 mono_json_writer_indent_pop (writer);
449 mono_json_writer_printf (writer, "\n");
450 mono_json_writer_indent (writer);
451 mono_json_writer_array_end (writer);
453 mono_json_writer_indent_pop (writer);
454 mono_json_writer_indent (writer);
455 mono_json_writer_object_end (writer);
458 void
459 mono_summarize_native_state_begin (void)
461 mono_json_writer_init_static ();
462 mono_native_state_add_prologue (&writer);
465 char *
466 mono_summarize_native_state_end (void)
468 mono_native_state_add_epilogue (&writer);
469 return writer.text->str;
472 void
473 mono_summarize_native_state_add_thread (MonoThreadSummary *thread, MonoContext *ctx)
475 mono_native_state_add_thread (&writer, thread, ctx);
478 #endif // HOST_WIN32