in src/profiler/elastic_apm_profiler/src/profiler/mod.rs [1112:1259]
fn jit_compilation_started(
&self,
function_id: FunctionID,
is_safe_to_block: BOOL,
) -> Result<(), HRESULT> {
if !IS_ATTACHED.load(Ordering::SeqCst) || is_safe_to_block == 0 {
return Ok(());
}
let modules = self.modules.lock().unwrap();
if !IS_ATTACHED.load(Ordering::SeqCst) {
return Ok(());
}
let profiler_borrow = self.profiler_info.borrow();
let profiler_info = profiler_borrow.as_ref().unwrap();
let function_info = profiler_info.get_function_info(function_id).map_err(|e| {
log::warn!(
"JITCompilationStarted: get function info failed for {}",
function_id
);
e
})?;
let module_metadata = modules.get(&function_info.module_id);
if module_metadata.is_none() {
return Ok(());
}
let module_metadata = module_metadata.unwrap();
let call_target_enabled = *env::ELASTIC_APM_PROFILER_CALLTARGET_ENABLED;
let loader_injected_in_app_domain = {
// scope reading to this block
self.first_jit_compilation_app_domains
.read()
.unwrap()
.contains(&module_metadata.app_domain_id)
};
// TODO investigate logging ONLY on MAIN() if MANAGED_PROFILER_LOADED is false
// TODO add MANAGED_PROFILER_LOADED and add same check for Elastic.Apm.dll
if call_target_enabled && loader_injected_in_app_domain {
return Ok(());
}
let caller = module_metadata
.import
.get_function_info(function_info.token)?;
log::trace!(
"JITCompilationStarted: function_id={}, name={}()",
function_id,
caller.full_name()
);
let is_desktop_iis = self.is_desktop_iis.load(Ordering::SeqCst);
let valid_startup_hook_callsite = if is_desktop_iis {
match &caller.type_info {
Some(t) => {
&module_metadata.assembly_name == "System.Web"
&& t.name == "System.Web.Compilation.BuildManager"
&& &caller.name == "InvokePreStartInitMethods"
}
None => false,
}
} else {
!(&module_metadata.assembly_name == "System"
|| &module_metadata.assembly_name == "System.Net.Http")
};
if valid_startup_hook_callsite && !loader_injected_in_app_domain {
let runtime_info_borrow = self.runtime_info.borrow();
let runtime_info = runtime_info_borrow.as_ref().unwrap();
let domain_neutral_assembly = runtime_info.is_desktop_clr()
&& self.cor_lib_module_loaded.load(Ordering::SeqCst)
&& self.cor_app_domain_id.load(Ordering::SeqCst) == module_metadata.app_domain_id;
log::info!(
"JITCompilationStarted: Startup hook registered in function_id={} token={} \
name={}() assembly_name={} app_domain_id={} domain_neutral={}",
function_id,
&function_info.token,
&caller.full_name(),
&module_metadata.assembly_name,
&module_metadata.app_domain_id,
domain_neutral_assembly
);
self.first_jit_compilation_app_domains
.write()
.unwrap()
.insert(module_metadata.app_domain_id);
startup_hook::run_il_startup_hook(
profiler_info,
&module_metadata,
function_info.module_id,
function_info.token,
)?;
if is_desktop_iis {
// TODO: hookup IIS module
}
}
if !call_target_enabled {
if &module_metadata.assembly_name == "Microsoft.AspNetCore.Hosting" {
return Ok(());
}
let method_replacements = module_metadata.get_method_replacements_for_caller(&caller);
if method_replacements.is_empty() {
return Ok(());
}
let mut module_wrapper_tokens = self.module_wrapper_tokens.lock().unwrap();
let mut module_wrapper_token = module_wrapper_tokens
.get_mut(&function_info.module_id)
.unwrap();
process::process_insertion_calls(
profiler_info,
&module_metadata,
&mut module_wrapper_token,
function_id,
function_info.module_id,
function_info.token,
&caller,
&method_replacements,
)?;
process::process_replacement_calls(
profiler_info,
&module_metadata,
&mut module_wrapper_token,
function_id,
function_info.module_id,
function_info.token,
&caller,
&method_replacements,
)?;
}
Ok(())
}