Profiler: add support embedded profilers whose entry point ends with _<profiler name>.
authorRolf Bjarne Kvinge <rolf@xamarin.com>
Thu, 13 Oct 2011 14:17:46 +0000 (16:17 +0200)
committerRolf Bjarne Kvinge <rolf@xamarin.com>
Wed, 26 Oct 2011 12:56:27 +0000 (14:56 +0200)
mono/metadata/profiler.c
mono/profiler/proflog.c

index 080ef41861b8dd6a315ba7e5e288af893651815f..4aadd1f98ee0e75c8045f5e9709ff5a4a59dde07 100644 (file)
@@ -1032,6 +1032,46 @@ typedef void (*ProfilerInitializer) (const char*);
 #define INITIALIZER_NAME "mono_profiler_startup"
 
 
+static gboolean
+load_profiler (MonoDl *pmodule, const char *desc, const char *symbol)
+{
+       char *err;
+       ProfilerInitializer func;
+
+       if (!pmodule)
+               return FALSE;
+
+       if ((err = mono_dl_symbol (pmodule, symbol, (gpointer *) &func))) {
+               g_free (err);
+               return FALSE;
+       } else {
+               func (desc);
+       }
+       return TRUE;
+}
+
+static gboolean
+load_embedded_profiler (const char *desc, const char *name)
+{
+       char *err = NULL;
+       char *symbol;
+       MonoDl *pmodule = NULL;
+       gboolean result;
+
+       pmodule = mono_dl_open (NULL, MONO_DL_LAZY, &err);
+       if (!pmodule) {
+               g_warning ("Could not open main executable (%s)", err);
+               g_free (err);
+               return FALSE;
+       }
+
+       symbol = g_strdup_printf (INITIALIZER_NAME "_%s", name);
+       result = load_profiler (pmodule, desc, symbol);
+       g_free (symbol);
+
+       return result;
+}
+
 static gboolean
 load_profiler_from_directory (const char *directory, const char *libname, const char *desc)
 {
@@ -1043,21 +1083,11 @@ load_profiler_from_directory (const char *directory, const char *libname, const
        iter = NULL;
        err = NULL;
        while ((path = mono_dl_build_path (directory, libname, &iter))) {
-               g_free (err);
                pmodule = mono_dl_open (path, MONO_DL_LAZY, &err);
-               if (pmodule) {
-                       ProfilerInitializer func;
-                       if ((err = mono_dl_symbol (pmodule, INITIALIZER_NAME, (gpointer *)&func))) {
-                               g_warning ("Cannot find initializer function %s in profiler module: %s (%s)", INITIALIZER_NAME, libname, err);
-                               g_free (err);
-                               err = NULL;
-                       } else {
-                               func (desc);
-                       }
-                       g_free (path);
-                       return TRUE;
-               }
                g_free (path);
+               g_free (err);
+               if (pmodule)
+                       return load_profiler (pmodule, desc, INITIALIZER_NAME);
        }
                
        return FALSE;
@@ -1119,15 +1149,18 @@ mono_profiler_load (const char *desc)
                } else {
                        mname = g_strdup (desc);
                }
-               libname = g_strdup_printf ("mono-profiler-%s", mname);
-               if (!load_profiler_from_directory (NULL, libname, desc)) {
+               if (!load_embedded_profiler (desc, mname)) {
+                       libname = g_strdup_printf ("mono-profiler-%s", mname);
+                       if (!load_profiler_from_directory (NULL, libname, desc))
 #if defined (MONO_ASSEMBLIES)
-                       res = load_profiler_from_directory (MONO_ASSEMBLIES, libname, desc);
+                               res = load_profiler_from_directory (mono_assembly_getrootdir (), libname, desc);
+#else
+                               res = FALSE;
 #endif
-                       if (!res)
-                               g_warning ("Error loading profiler module '%s'", libname);
-               }                       
-               g_free (libname);
+                               if (!res)
+                                       g_warning ("The %s profiler wasn't found in the main executable nor could it be loaded from '%s'.", libname);
+                       g_free (libname);
+               }
                g_free (mname);
        }
        g_free (cdesc);
index 87b59cd080472b99cbe0ee9659a594c4e0297306..5a539ce8c0ff015ab9571183bebbd2fa28f23402 100644 (file)
@@ -2198,6 +2198,19 @@ set_hsmode (char* val, int allow_empty)
 extern void
 mono_profiler_startup (const char *desc);
 
+extern void
+mono_profiler_startup_log (const char *desc);
+
+/*
+ * this is the entry point that will be used when the profiler
+ * is embedded inside the main executable.
+ */
+void
+mono_profiler_startup_log (const char *desc)
+{
+       mono_profiler_startup (desc);
+}
+
 void
 mono_profiler_startup (const char *desc)
 {