MonoProfileGCHandleFunc gc_handle;
MonoProfileGCRootFunc gc_roots;
+ MonoProfileGCFinalizeFunc gc_finalize_begin;
+ MonoProfileGCFinalizeObjectFunc gc_finalize_object_begin;
+ MonoProfileGCFinalizeObjectFunc gc_finalize_object_end;
+ MonoProfileGCFinalizeFunc gc_finalize_end;
+
MonoProfileFunc runtime_initialized_event;
MonoProfilerCodeChunkNew code_chunk_new;
prof_list->gc_roots = roots_callback;
}
+void
+mono_profiler_gc_finalize_begin (void)
+{
+ for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+ if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_begin)
+ prof->gc_finalize_begin (prof->profiler);
+}
+
+void
+mono_profiler_gc_finalize_object_begin (MonoObject *obj)
+{
+ for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+ if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_object_begin)
+ prof->gc_finalize_object_begin (prof->profiler, obj);
+}
+
+void
+mono_profiler_gc_finalize_object_end (MonoObject *obj)
+{
+ for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+ if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_object_end)
+ prof->gc_finalize_object_end (prof->profiler, obj);
+}
+
+void
+mono_profiler_gc_finalize_end (void)
+{
+ for (ProfilerDesc *prof = prof_list; prof; prof = prof->next)
+ if ((prof->events & MONO_PROFILE_GC_FINALIZATION) && prof->gc_finalize_end)
+ prof->gc_finalize_end (prof->profiler);
+}
+
+void
+mono_profiler_install_gc_finalize (MonoProfileGCFinalizeFunc begin, MonoProfileGCFinalizeObjectFunc begin_obj, MonoProfileGCFinalizeObjectFunc end_obj, MonoProfileGCFinalizeFunc end)
+{
+ if (!prof_list)
+ return;
+
+ prof_list->gc_finalize_begin = begin;
+ prof_list->gc_finalize_object_begin = begin_obj;
+ prof_list->gc_finalize_object_begin = end_obj;
+ prof_list->gc_finalize_end = end;
+}
+
void
mono_profiler_install_runtime_initialized (MonoProfileFunc runtime_initialized_callback)
{
MonoDl *pmodule = NULL;
gboolean result;
- pmodule = mono_dl_open (NULL, MONO_DL_LAZY, &err);
+ /*
+ * Some profilers (such as ours) may need to call back into the runtime
+ * from their sampling callback (which is called in async-signal context).
+ * They need to be able to know that all references back to the runtime
+ * have been resolved; otherwise, calling runtime functions may result in
+ * invoking the dynamic linker which is not async-signal-safe. Passing
+ * MONO_DL_EAGER will ask the dynamic linker to resolve everything upfront.
+ */
+ pmodule = mono_dl_open (NULL, MONO_DL_EAGER, &err);
if (!pmodule) {
g_warning ("Could not open main executable (%s)", err);
g_free (err);
iter = NULL;
err = NULL;
while ((path = mono_dl_build_path (directory, libname, &iter))) {
- pmodule = mono_dl_open (path, MONO_DL_LAZY, &err);
+ pmodule = mono_dl_open (path, MONO_DL_EAGER, &err);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "Attempting to load profiler: %s, %ssuccessful, err: %s", path, pmodule?"":"not ", err);
g_free (path);
g_free (err);
load_profiler_from_mono_installation (const char *libname, const char *desc)
{
char *err = NULL;
- MonoDl *pmodule = mono_dl_open_runtime_lib (libname, MONO_DL_LAZY, &err);
+ MonoDl *pmodule = mono_dl_open_runtime_lib (libname, MONO_DL_EAGER, &err);
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "Attempting to load profiler from runtime libs: %s, %ssuccessful, err: %s", libname, pmodule?"":"not ", err);
g_free (err);
if (pmodule)