From bd4c05057c66439e420835eaf06ef325e91f7f4d Mon Sep 17 00:00:00 2001 From: Brian Robbins Date: Wed, 21 Oct 2015 16:34:42 -0700 Subject: [PATCH] Initialize LTTng tracepoint provider as part of loading libcoreclr.so. --- src/pal/inc/pal.h | 20 +++++++++++ src/pal/src/misc/miscpalapi.cpp | 74 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h index 7bddd88..d2d5ed9 100644 --- a/src/pal/inc/pal.h +++ b/src/pal/inc/pal.h @@ -491,6 +491,26 @@ typedef long time_t; typedef DWORD (PALAPI *PTHREAD_START_ROUTINE)(LPVOID lpThreadParameter); typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + +/******************* Tracing Initialization *******************************/ + +#if defined(__LINUX__) + +// Constructor priority is set to 200, which allows for constructors to +// guarantee that they run before or after this constructor by setting +// their priority appropriately. + +// Priority values must be greater than 100. The lower the value, +// the higher the priority. +static +void +__attribute__((__unused__)) +__attribute__((constructor (200))) +PAL_InitializeTracing(void); + +#endif + + /******************* PAL-Specific Entrypoints *****************************/ PALIMPORT diff --git a/src/pal/src/misc/miscpalapi.cpp b/src/pal/src/misc/miscpalapi.cpp index 0aeeb89..206a5b7 100644 --- a/src/pal/src/misc/miscpalapi.cpp +++ b/src/pal/src/misc/miscpalapi.cpp @@ -50,6 +50,80 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC); static const char RANDOM_DEVICE_NAME[] ="/dev/random"; static const char URANDOM_DEVICE_NAME[]="/dev/urandom"; + +/*++ + +Initialization logic for LTTng tracepoint providers. + +--*/ +#if defined(__LINUX__) + +static const char tpLibName[] = "libcoreclrtraceptprovider.so"; + + +/*++ + +NOTE: PAL_InitializeTracing MUST NOT depend on anything in the PAL itself +as it is called prior to PAL initialization. + +--*/ +static +void +PAL_InitializeTracing(void) +{ + // Get the path to the currently executing shared object (libcoreclr.so). + Dl_info info; + int succeeded = dladdr((void *)PAL_InitializeTracing, &info); + if(!succeeded) + { + return; + } + + // Copy the path and modify the shared object name to be the tracepoint provider. + char tpProvPath[MAX_LONGPATH]; + int pathLen = strlen(info.dli_fname); + int tpLibNameLen = strlen(tpLibName); + + // Find the length of the full path without the shared object name, including the trailing slash. + int lastTrailingSlashLen = -1; + for(int i=pathLen-1; i>=0; i--) + { + if(info.dli_fname[i] == '/') + { + lastTrailingSlashLen = i+1; + break; + } + } + + // Make sure we found the last trailing slash. + if(lastTrailingSlashLen == -1) + { + return; + } + + // Make sure that the final path is shorter than MAX_PATH. + // +1 ensures that the string can be NULL-terminated. + if((lastTrailingSlashLen + tpLibNameLen + 1) > MAX_LONGPATH) + { + return; + } + + // Copy the path without the shared object name. + memcpy(&tpProvPath, info.dli_fname, lastTrailingSlashLen); + + // Append the shared object name for the tracepoint provider. + memcpy(&tpProvPath[lastTrailingSlashLen], &tpLibName, tpLibNameLen); + + // NULL-terminate the string. + tpProvPath[lastTrailingSlashLen + tpLibNameLen] = '\0'; + + // Load the tracepoint provider. + // It's OK if this fails - that just means that tracing dependencies aren't available. + dlopen(tpProvPath, RTLD_NOW | RTLD_GLOBAL); +} + +#endif + /*++ Function : -- 2.7.4