Skip to content

Commit

Permalink
Store entry assembly path for easy access for diagnostics (#95045)
Browse files Browse the repository at this point in the history
- Add `g_EntryAssemblyPath` global variable holding the full path to the entry assembly
  - Set right before loading the entry assembly (so also before startup hooks are run) - NULL if there is no entry assembly
- Ensure value is included dumps
  - For triage dumps, the dumped value is updated to only be the assembly file name instead of the full path
  • Loading branch information
elinor-fung committed Nov 21, 2023
1 parent 7dc2e67 commit b126b9a
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 2 deletions.
28 changes: 28 additions & 0 deletions src/coreclr/debug/daccess/enummem.cpp
Expand Up @@ -224,6 +224,34 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)

ReportMem(g_gcDacGlobals.GetAddr(), sizeof(GcDacVars));

PTR_WSTR entryAssemblyPath = (PTR_WSTR)g_EntryAssemblyPath;
entryAssemblyPath.EnumMem();

// Triage dumps must not include full paths (PII data). Replace entry assembly path with file name only.
if (flags == CLRDATA_ENUM_MEM_TRIAGE)
{
WCHAR* path = entryAssemblyPath;
if (path != NULL)
{
size_t pathLen = u16_strlen(path) + 1;

// Get the file name based on the last directory separator
const WCHAR* name = u16_strrchr(path, DIRECTORY_SEPARATOR_CHAR_W);
if (name != NULL)
{
name += 1;
size_t len = u16_strlen(name) + 1;
wcscpy_s(path, len, name);

// Null out the rest of the buffer
for (size_t i = len; i < pathLen; ++i)
path[i] = W('\0');

DacUpdateMemoryRegion(entryAssemblyPath.GetAddr(), pathLen, (BYTE*)path);
}
}
}

// We need all of the dac variables referenced by the GC DAC global struct.
// This struct contains pointers to pointers, so we first dereference the pointers
// to obtain the location of the variable that's reported.
Expand Down
6 changes: 4 additions & 2 deletions src/coreclr/inc/daccess.h
Expand Up @@ -574,6 +574,8 @@
#include "crosscomp.h"
#endif

#include <dn-u16.h>

// Information stored in the DAC table of interest to the DAC implementation
// Note that this information is shared between all instantiations of ClrDataAccess, so initialize
// it just once in code:ClrDataAccess.GetDacGlobals (rather than use fields in ClrDataAccess);
Expand Down Expand Up @@ -1493,10 +1495,10 @@ class __Str16Ptr : public __DPtr<WCHAR>
}
void EnumMem(void) const
{
char* str = DacInstantiateStringW(m_addr, maxChars, false);
WCHAR* str = DacInstantiateStringW(m_addr, maxChars, false);
if (str)
{
DacEnumMemoryRegion(m_addr, strlen(str) + 1);
DacEnumMemoryRegion(m_addr, u16_strlen(str) + 1);
}
}
};
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/inc/dacvars.h
Expand Up @@ -231,5 +231,7 @@ DEFINE_DACVAR(SIZE_T, dac__g_clrNotificationArguments, ::g_clrNotificationArgume
DEFINE_DACVAR(bool, dac__g_metadataUpdatesApplied, ::g_metadataUpdatesApplied)
#endif

DEFINE_DACVAR(PTR_WSTR, dac__g_EntryAssemblyPath, ::g_EntryAssemblyPath)

#undef DEFINE_DACVAR
#undef DEFINE_DACVAR_NO_DUMP
9 changes: 9 additions & 0 deletions src/coreclr/vm/corhost.cpp
Expand Up @@ -310,6 +310,15 @@ HRESULT CorHost2::ExecuteAssembly(DWORD dwAppDomainId,

_ASSERTE (!pThread->PreemptiveGCDisabled());

if (g_EntryAssemblyPath == NULL)
{
// Store the entry assembly path for diagnostic purposes (for example, dumps)
size_t len = u16_strlen(pwzAssemblyPath) + 1;
NewArrayHolder<WCHAR> path { new WCHAR[len] };
wcscpy_s(path, len, pwzAssemblyPath);
g_EntryAssemblyPath = path.Extract();
}

Assembly *pAssembly = AssemblySpec::LoadAssembly(pwzAssemblyPath);

#if defined(FEATURE_MULTICOREJIT)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/vars.cpp
Expand Up @@ -106,6 +106,8 @@ GVAL_IMPL_INIT(DWORD, g_debuggerWordTLSIndex, TLS_OUT_OF_INDEXES);
#endif
GVAL_IMPL_INIT(DWORD, g_TlsIndex, TLS_OUT_OF_INDEXES);

GVAL_IMPL_INIT(PTR_WSTR, g_EntryAssemblyPath, NULL);

#ifndef DACCESS_COMPILE

// <TODO> @TODO - PROMOTE. </TODO>
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/vars.hpp
Expand Up @@ -389,6 +389,9 @@ GVAL_DECL(DWORD, g_debuggerWordTLSIndex);
#endif
GVAL_DECL(DWORD, g_TlsIndex);

// Full path to the managed entry assembly - stored for ease of identifying the entry asssembly for diagnostics
GVAL_DECL(PTR_WSTR, g_EntryAssemblyPath);

// Global System Information
extern SYSTEM_INFO g_SystemInfo;

Expand Down

0 comments on commit b126b9a

Please sign in to comment.