Skip to content

Commit

Permalink
[profiler] Load the profiler with MONO_DL_EAGER.
Browse files Browse the repository at this point in the history
We need to make sure all external references have been resolved so that we
don't invoke the dynamic linker in the mono_sample_hit () callback which is
called in async-signal context.
  • Loading branch information
Alex Rønne Petersen authored and kumpera committed Apr 19, 2016
1 parent 49b6089 commit e91ee2b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 3 deletions.
14 changes: 11 additions & 3 deletions mono/metadata/profiler.c
Expand Up @@ -1147,7 +1147,15 @@ load_embedded_profiler (const char *desc, const char *name)
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);
Expand Down Expand Up @@ -1175,7 +1183,7 @@ load_profiler_from_directory (const char *directory, const char *libname, const
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);
Expand All @@ -1190,7 +1198,7 @@ static gboolean
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)
Expand Down
8 changes: 8 additions & 0 deletions mono/profiler/proflog.c
Expand Up @@ -2063,6 +2063,14 @@ enqueue_sample_hit (gpointer p)
static void
mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
{
/*
* Please note: We rely on the runtime loading the profiler with
* MONO_DL_EAGER (RTLD_NOW) so that references to runtime functions within
* this function (and its siblings) are resolved when the profiler is
* loaded. Otherwise, we would potentially invoke the dynamic linker when
* invoking runtime functions, which is not async-signal-safe.
*/

if (in_shutdown)
return;

Expand Down

0 comments on commit e91ee2b

Please sign in to comment.