Skip to content

Commit

Permalink
Apply changes from dotnet#63356
Browse files Browse the repository at this point in the history
  • Loading branch information
John Salem authored May 4, 2022
1 parent 5992145 commit 24a80c0
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ CrstStatic _ep_rt_coreclr_config_lock;

thread_local EventPipeCoreCLRThreadHolderTLS EventPipeCoreCLRThreadHolderTLS::g_threadHolderTLS;

ep_char8_t *_ep_rt_coreclr_diagnostics_cmd_line;
ep_char8_t *volatile _ep_rt_coreclr_diagnostics_cmd_line;

#ifndef TARGET_UNIX
uint32_t *_ep_rt_coreclr_proc_group_offsets;
Expand Down
37 changes: 28 additions & 9 deletions src/coreclr/vm/eventing/eventpipe/ep-rt-coreclr.h
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,15 @@ ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected,
return static_cast<size_t>(InterlockedCompareExchangeT<size_t> (target, value, expected));
}

static
inline
ep_char8_t *
ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value)
{
STATIC_CONTRACT_NOTHROW;
return static_cast<ep_char8_t *>(InterlockedCompareExchangeT<ep_char8_t *> (target, value, expected));
}

/*
* EventPipe.
*/
Expand Down Expand Up @@ -2664,19 +2673,29 @@ ep_rt_diagnostics_command_line_get (void)
STATIC_CONTRACT_NOTHROW;

// In coreclr, this value can change over time, specifically before vs after suspension in diagnostics server.
// The host initalizes the runtime in two phases, init and exec assembly. On non-Windows platforms the commandline returned by the runtime
// The host initializes the runtime in two phases, init and exec assembly. On non-Windows platforms the commandline returned by the runtime
// is different during each phase. We suspend during init where the runtime has populated the commandline with a
// mock value (the full path of the executing assembly) and the actual value isn't populated till the exec assembly phase.
// On Windows this does not apply as the value is retrieved directly from the OS any time it is requested.
// On Windows this does not apply as the value is retrieved directly from the OS any time it is requested.
// As a result, we cannot actually cache this value. We need to return the _current_ value.
// This function needs to handle freeing the string in order to make it consistent with Mono's version.
// To that end, we'll "cache" it here so we free the previous string when we get it again.
extern ep_char8_t *_ep_rt_coreclr_diagnostics_cmd_line;

if (_ep_rt_coreclr_diagnostics_cmd_line)
ep_rt_utf8_string_free(_ep_rt_coreclr_diagnostics_cmd_line);

_ep_rt_coreclr_diagnostics_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(GetCommandLineForDiagnostics ()), -1);
// There is a rare chance this may be called on multiple threads, so we attempt to always return the newest value
// and conservatively leak the old value if it changed. This is extremely rare and should only leak 1 string.
extern ep_char8_t *volatile _ep_rt_coreclr_diagnostics_cmd_line;

ep_char8_t *old_cmd_line = _ep_rt_coreclr_diagnostics_cmd_line;
ep_char8_t *new_cmd_line = ep_rt_utf16_to_utf8_string (reinterpret_cast<const ep_char16_t *>(GetCommandLineForDiagnostics ()), -1);
if (old_cmd_line && ep_rt_utf8_string_compare (old_cmd_line, new_cmd_line) == 0) {
// same as old, so free the new one
ep_rt_utf8_string_free (new_cmd_line);
} else {
// attempt an update, and give up if you lose the race
if (ep_rt_atomic_compare_exchange_utf8_string (&_ep_rt_coreclr_diagnostics_cmd_line, old_cmd_line, new_cmd_line) != old_cmd_line) {
ep_rt_utf8_string_free (new_cmd_line);
}
// NOTE: If there was a value we purposefully leak it since it may still be in use.
// This leak is *small* (length of the command line) and bounded (should only happen once)
}

return _ep_rt_coreclr_diagnostics_cmd_line;
}
Expand Down
8 changes: 8 additions & 0 deletions src/mono/mono/eventpipe/ep-rt-mono.h
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,14 @@ ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected,
#endif
}

static
inline
ep_char8_t *
ep_rt_atomic_compare_exchange_utf8_string (ep_char8_t *volatile *target, ep_char8_t *expected, ep_char8_t *value)
{
return (ep_char8_t *)mono_atomic_cas_ptr ((volatile gpointer *)target, (gpointer)value, (gpointer)expected);
}

/*
* EventPipe.
*/
Expand Down
4 changes: 4 additions & 0 deletions src/native/eventpipe/ep-rt.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ static
size_t
ep_rt_atomic_compare_exchange_size_t (volatile size_t *target, size_t expected, size_t value);

static
ep_char8_t *
eo_rt_atomic_compare_exchange_utf8_string (volatile ep_char8_t **target, ep_char8_t *expected, ep_char8_t *value);

/*
* EventPipe.
*/
Expand Down

0 comments on commit 24a80c0

Please sign in to comment.