* Fix missing metadata in Linux core dumps.
Issue #https://github.com/dotnet/diagnostics/issues/56
Both Windows and Linux minidumps don't save all the assemblies' metadata which can cause
stack traces to display !Unknown. On Windows most debuggers like Windbg and VS can load
the module from file for this kind of dumps. On Linux lldb/SOS doesn't load the native
modules and really doesn't know anything about the managed assemblies.
Add metadata callback to datatarget and it's implementation in SOS.NETCore.
Add IsMetadataMemory() and the metadata region list. This is because lldb on core dumps
returns 0's on missing metadata memory reads instead of an error.
int localIndex,
out IntPtr localVarName);
+ private delegate int GetMetadataLocatorDelegate(
+ [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
+ uint imageTimestamp,
+ uint imageSize,
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
+ uint mdRva,
+ uint flags,
+ uint bufferSize,
+ IntPtr buffer,
+ IntPtr dataSize);
+
#endregion
/// <summary>
public ResolveSequencePointDelegate ResolveSequencePointDelegate;
public GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
public GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
+ public GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
}
static SOSNetCoreCallbacks s_callbacks = new SOSNetCoreCallbacks {
DisposeDelegate = SymbolReader.Dispose,
ResolveSequencePointDelegate = SymbolReader.ResolveSequencePoint,
GetLineByILOffsetDelegate = SymbolReader.GetLineByILOffset,
- GetLocalVariableNameDelegate = SymbolReader.GetLocalVariableName,
+ GetLocalVariableNameDelegate = SymbolReader.GetLocalVariableName,
+ GetMetadataLocatorDelegate = MetadataHelper.GetMetadataLocator
};
static readonly string s_coreclrModuleName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "coreclr" : "libcoreclr.so";
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.SymbolStore;
+using Microsoft.SymbolStore.KeyGenerators;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection.Metadata.Ecma335;
+using System.Reflection.PortableExecutable;
+using System.Runtime.InteropServices;
+
+namespace SOS
+{
+ public class MetadataHelper
+ {
+ public static int GetMetadataLocator(
+ [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
+ uint imageTimestamp,
+ uint imageSize,
+ [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
+ uint mdRva,
+ uint flags,
+ uint bufferSize,
+ IntPtr pMetadata,
+ IntPtr pMetadataSize)
+ {
+ int hr = unchecked((int)0x80004005);
+ int dataSize = 0;
+
+ Debug.Assert(pMetadata != IntPtr.Zero);
+
+ Stream peStream = null;
+ if (imagePath != null && File.Exists(imagePath))
+ {
+ peStream = SymbolReader.TryOpenFile(imagePath);
+ }
+ else if (SymbolReader.IsSymbolStoreEnabled())
+ {
+ SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
+ peStream = SymbolReader.GetSymbolStoreFile(key)?.Stream;
+ }
+ if (peStream != null)
+ {
+ using (var peReader = new PEReader(peStream, PEStreamOptions.Default))
+ {
+ if (peReader.HasMetadata)
+ {
+ PEMemoryBlock metadataInfo = peReader.GetMetadata();
+ unsafe
+ {
+ int size = Math.Min((int)bufferSize, metadataInfo.Length);
+ Marshal.Copy(metadataInfo.GetContent().ToArray(), 0, pMetadata, size);
+ }
+ dataSize = metadataInfo.Length;
+ hr = 0;
+ }
+ }
+ }
+
+ if (pMetadataSize != IntPtr.Zero)
+ {
+ Marshal.WriteInt32(pMetadataSize, dataSize);
+ }
+ return hr;
+ }
+ }
+}
/// <param name="readMemory">read memory callback delegate</param>
public static void LoadNativeSymbols(SymbolFileCallback callback, IntPtr parameter, string tempDirectory, string moduleFilePath, ulong address, int size, ReadMemoryDelegate readMemory)
{
- if (s_symbolStore != null)
+ if (IsSymbolStoreEnabled())
{
Debug.Assert(s_tracer != null);
Stream stream = new TargetStream(address, size, readMemory);
if (pdbStream == null)
{
- if (s_symbolStore == null)
+ if (IsSymbolStoreEnabled())
{
- return null;
+ Debug.Assert(codeViewEntry.MinorVersion == ImageDebugDirectory.PortablePDBMinorVersion);
+ SymbolStoreKey key = PortablePDBFileKeyGenerator.GetKey(pdbPath, data.Guid);
+ pdbStream = GetSymbolStoreFile(key)?.Stream;
}
- Debug.Assert(codeViewEntry.MinorVersion == ImageDebugDirectory.PortablePDBMinorVersion);
- SymbolStoreKey key = PortablePDBFileKeyGenerator.GetKey(pdbPath, data.Guid);
- pdbStream = GetSymbolStoreFile(key)?.Stream;
if (pdbStream == null)
{
return null;
return result;
}
+ /// <summary>
+ /// Returns true if symbol download has been enabled.
+ /// </summary>
+ internal static bool IsSymbolStoreEnabled()
+ {
+ return s_symbolStore != null;
+ }
+
/// <summary>
/// Attempts to download/retrieve from cache the key.
/// </summary>
/// <param name="key">index of the file to retrieve</param>
/// <returns>stream or null</returns>
- private static SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
+ internal static SymbolStoreFile GetSymbolStoreFile(SymbolStoreKey key)
{
try
{
/// </summary>
/// <param name="path">file path</param>
/// <returns>stream or null if doesn't exist or error</returns>
- private static Stream TryOpenFile(string path)
+ internal static Stream TryOpenFile(string path)
{
if (!File.Exists(path))
{
AddRef();
return S_OK;
}
+ else if (InterfaceId == IID_ICLRMetadataLocator)
+ {
+ *Interface = (ICLRMetadataLocator*)this;
+ AddRef();
+ return S_OK;
+ }
else
{
*Interface = NULL;
{
return E_UNEXPECTED;
}
+#ifdef FEATURE_PAL
+ if (g_sos != nullptr)
+ {
+ // LLDB synthesizes memory (returns 0's) for missing pages (in this case the missing metadata
+ // pages) in core dumps. This functions creates a list of the metadata regions and returns true
+ // if the read would be in the metadata of a loaded assembly. This allows an error to be returned
+ // instead of 0's so the DAC will call the GetMetadataLocator datatarget callback.
+ if (IsMetadataMemory(address, request))
+ {
+ return E_ACCESSDENIED;
+ }
+ }
+#endif
return g_ExtData->ReadVirtual(address, (PVOID)buffer, request, (PULONG)done);
}
return E_NOTIMPL;
}
+// ICorDebugDataTarget4
+
HRESULT STDMETHODCALLTYPE
DataTarget::VirtualUnwind(
/* [in] */ DWORD threadId,
return E_NOTIMPL;
#endif
}
+
+// ICLRMetadataLocator
+
+HRESULT STDMETHODCALLTYPE
+DataTarget::GetMetadata(
+ /* [in] */ LPCWSTR imagePath,
+ /* [in] */ ULONG32 imageTimestamp,
+ /* [in] */ ULONG32 imageSize,
+ /* [in] */ GUID* mvid,
+ /* [in] */ ULONG32 mdRva,
+ /* [in] */ ULONG32 flags,
+ /* [in] */ ULONG32 bufferSize,
+ /* [out, size_is(bufferSize), length_is(*dataSize)] */
+ BYTE* buffer,
+ /* [out] */ ULONG32* dataSize)
+{
+ HRESULT hr = InitializeHosting();
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+ InitializeSymbolStore();
+ _ASSERTE(g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate != nullptr);
+ return g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate(imagePath, imageTimestamp, imageSize, mvid, mdRva, flags, bufferSize, buffer, dataSize);
+}
+
+
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-class DataTarget : public ICLRDataTarget, ICorDebugDataTarget4
+class DataTarget : public ICLRDataTarget, ICorDebugDataTarget4, ICLRMetadataLocator
{
private:
LONG m_ref; // Reference count.
/* [in] */ DWORD threadId,
/* [in] */ ULONG32 contextSize,
/* [in, out, size_is(contextSize)] */ PBYTE context);
+
+ // ICLRMetadataLocator
+
+ virtual HRESULT STDMETHODCALLTYPE GetMetadata(
+ /* [in] */ LPCWSTR imagePath,
+ /* [in] */ ULONG32 imageTimestamp,
+ /* [in] */ ULONG32 imageSize,
+ /* [in] */ GUID* mvid,
+ /* [in] */ ULONG32 mdRva,
+ /* [in] */ ULONG32 flags,
+ /* [in] */ ULONG32 bufferSize,
+ /* [out, size_is(bufferSize), length_is(*dataSize)] */
+ BYTE* buffer,
+ /* [out] */ ULONG32* dataSize);
};
\ No newline at end of file
// Print out real code address in place of the copy address
//
- ExtOut("%08x`%08x ", (ULONG)(InstrAddr >> 32), (ULONG)InstrAddr);
+ ExtOut("%08x`%08x ", (ULONG)(InstrAddr >> 32), (ULONG)InstrAddr);
ptr = line;
NextTerm (ptr);
static void DllsNameFromPeb(
ULONG_PTR addrContaining,
__out_ecount (MAX_LONGPATH) WCHAR *dllName
- )
+ )
{
ULONG64 ProcessPeb;
g_ExtSystem->GetCurrentProcessPeb (&ProcessPeb);
#ifndef _ASSERTE
#ifdef _DEBUG
-#define _ASSERTE(expr) \
+#define _ASSERTE(expr) \
do { if (!(expr) ) { ExtOut(#expr); DebugBreak(); } } while (0)
#else // _DEBUG
#define _ASSERTE(expr)
std::set<std::string> addedAssemblies;
// Don't add this file to the list because we don't want to the one from the hosting runtime
- addedAssemblies.insert(SymbolReaderDllName);
+ addedAssemblies.insert(SOSManagedDllName);
// Walk the directory for each extension separately so that we first get files with .ni.dll extension,
// then files with .dll extension, etc.
return Status;
}
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "InitializeSymbolStore", (void **)&g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "DisplaySymbolStore", (void **)&g_SOSNetCoreCallbacks.DisplaySymbolStoreDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "DisableSymbolStore", (void **)&g_SOSNetCoreCallbacks.DisableSymbolStoreDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "LoadNativeSymbols", (void **)&g_SOSNetCoreCallbacks.LoadNativeSymbolsDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "LoadSymbolsForModule", (void **)&g_SOSNetCoreCallbacks.LoadSymbolsForModuleDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "Dispose", (void **)&g_SOSNetCoreCallbacks.DisposeDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "ResolveSequencePoint", (void **)&g_SOSNetCoreCallbacks.ResolveSequencePointDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetLocalVariableName", (void **)&g_SOSNetCoreCallbacks.GetLocalVariableNameDelegate));
- IfFailRet(createDelegate(hostHandle, domainId, SymbolReaderDllName, SymbolReaderClassName, "GetLineByILOffset", (void **)&g_SOSNetCoreCallbacks.GetLineByILOffsetDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "InitializeSymbolStore", (void **)&g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "DisplaySymbolStore", (void **)&g_SOSNetCoreCallbacks.DisplaySymbolStoreDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "DisableSymbolStore", (void **)&g_SOSNetCoreCallbacks.DisableSymbolStoreDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "LoadNativeSymbols", (void **)&g_SOSNetCoreCallbacks.LoadNativeSymbolsDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "LoadSymbolsForModule", (void **)&g_SOSNetCoreCallbacks.LoadSymbolsForModuleDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "Dispose", (void **)&g_SOSNetCoreCallbacks.DisposeDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "ResolveSequencePoint", (void **)&g_SOSNetCoreCallbacks.ResolveSequencePointDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "GetLocalVariableName", (void **)&g_SOSNetCoreCallbacks.GetLocalVariableNameDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, SymbolReaderClassName, "GetLineByILOffset", (void **)&g_SOSNetCoreCallbacks.GetLineByILOffsetDelegate));
+ IfFailRet(createDelegate(hostHandle, domainId, SOSManagedDllName, MetadataHelperClassName, "GetMetadataLocator", (void **)&g_SOSNetCoreCallbacks.GetMetadataLocatorDelegate));
g_hostingInitialized = true;
return Status;
return S_OK;
}
+/**********************************************************************\
+ * Setup and initialize the symbol server support using the .sympath
+\**********************************************************************/
+void InitializeSymbolStore()
+{
+ _ASSERTE(g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate != nullptr);
+
+#ifndef FEATURE_PAL
+ if (!g_symbolStoreInitialized)
+ {
+ g_symbolStoreInitialized = true;
+
+ ArrayHolder<char> symbolPath = new char[MAX_LONGPATH];
+ if (SUCCEEDED(g_ExtSymbols->GetSymbolPath(symbolPath, MAX_LONGPATH, nullptr)))
+ {
+ if (strlen(symbolPath) > 0)
+ {
+ if (!g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate(false, false, false, nullptr, nullptr, symbolPath))
+ {
+ ExtErr("Windows symbol path parsing FAILED\n");
+ }
+ }
+ }
+ }
+#endif
+}
+
/**********************************************************************\
* Enumerate the native modules and attempt to download the symbols
* for them. Depends on the lldb callback to enumerate modules. Not
HRESULT Status = S_OK;
IfFailRet(InitializeHosting());
+ InitializeSymbolStore();
_ASSERTE(g_SOSNetCoreCallbacks.LoadSymbolsForModuleDelegate != nullptr);
- _ASSERTE(g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate != nullptr);
-
-#ifndef FEATURE_PAL
- if (!g_symbolStoreInitialized)
- {
- g_symbolStoreInitialized = true;
-
- ArrayHolder<char> symbolPath = new char[MAX_LONGPATH];
- if (SUCCEEDED(g_ExtSymbols->GetSymbolPath(symbolPath, MAX_LONGPATH, nullptr)))
- {
- if (strlen(symbolPath) > 0)
- {
- if (!g_SOSNetCoreCallbacks.InitializeSymbolStoreDelegate(false, false, false, nullptr, nullptr, symbolPath))
- {
- ExtErr("Windows symbol path parsing FAILED\n");
- }
- }
- }
- }
-#endif
// The module name needs to be null for in-memory PE's.
ArrayHolder<char> szModuleName = nullptr;
#include <soshostservices.h>
-static const char *SymbolReaderDllName = "SOS.NETCore";
+static const char *SOSManagedDllName = "SOS.NETCore";
static const char *SymbolReaderClassName = "SOS.SymbolReader";
+static const char *MetadataHelperClassName = "SOS.MetadataHelper";
extern HMODULE g_hInstance;
extern LPCSTR g_hostRuntimeDirectory;
extern BOOL IsHostingInitialized();
extern HRESULT InitializeHosting();
extern HRESULT InitializeSymbolStore(BOOL logging, BOOL msdl, BOOL symweb, const char* symbolServer, const char* cacheDirectory);
+extern void InitializeSymbolStore();
extern HRESULT LoadNativeSymbols(bool runtimeOnly = false);
extern void DisplaySymbolStore();
extern void DisableSymbolStore();
{
TADDR mt = GetMT();
MethodTableInfo* info = g_special_mtCache.Lookup((DWORD_PTR)mt);
- if (!info->IsInitialized())
+ if (!info->IsInitialized())
{
// this is the first time we see this method table, so we need to get the information
// from the target
typedef BOOL (*GetLocalVariableNameDelegate)(PVOID, int, int, BSTR*);
typedef BOOL (*GetLineByILOffsetDelegate)(PVOID, mdMethodDef, ULONG64, ULONG *, BSTR*);
-#define SOSNetCoreCallbacksVersion 1
+typedef BOOL (*GetMetadataLocatorDelegate)(
+ LPCWSTR imagePath,
+ unsigned int imageTimestamp,
+ unsigned int imageSize,
+ GUID* mvid,
+ unsigned int mdRva,
+ unsigned int flags,
+ unsigned int bufferSize,
+ PVOID pMetadata,
+ unsigned int* pMetadataSize
+);
+
+#define SOSNetCoreCallbacksVersion 2
struct SOSNetCoreCallbacks
{
ResolveSequencePointDelegate ResolveSequencePointDelegate;
GetLineByILOffsetDelegate GetLineByILOffsetDelegate;
GetLocalVariableNameDelegate GetLocalVariableNameDelegate;
+ GetMetadataLocatorDelegate GetMetadataLocatorDelegate;
};
MIDL_INTERFACE("D13608FB-AD14-4B49-990A-80284F934C41")
INIT_API();
g_clrData->Flush();
+#ifdef FEATURE_PAL
+ FlushMetadataRegions();
+#endif
return Status;
} // DECLARE_API( SOSFlush )
return S_OK;
}
+
+#ifdef FEATURE_PAL
+
+struct MemoryRegion
+{
+private:
+ uint64_t m_startAddress;
+ uint64_t m_endAddress;
+
+public:
+ MemoryRegion(uint64_t start, uint64_t end) :
+ m_startAddress(start),
+ m_endAddress(end)
+ {
+ }
+
+ // copy constructor
+ MemoryRegion(const MemoryRegion& region) :
+ m_startAddress(region.m_startAddress),
+ m_endAddress(region.m_endAddress)
+ {
+ }
+
+ uint64_t StartAddress() const { return m_startAddress; }
+ uint64_t EndAddress() const { return m_endAddress; }
+ uint64_t Size() const { return m_endAddress - m_startAddress; }
+
+ bool operator<(const MemoryRegion& rhs) const
+ {
+ return (m_startAddress < rhs.m_startAddress) && (m_endAddress <= rhs.m_startAddress);
+ }
+
+ // Returns true if "rhs" is wholly contained in this one
+ bool Contains(const MemoryRegion& rhs) const
+ {
+ return (m_startAddress <= rhs.m_startAddress) && (m_endAddress >= rhs.m_endAddress);
+ }
+};
+
+std::set<MemoryRegion> g_metadataRegions;
+bool g_metadataRegionsPopulated = false;
+
+void FlushMetadataRegions()
+{
+ g_metadataRegionsPopulated = false;
+}
+
+//-------------------------------------------------------------------------------
+// Lifted from "..\md\inc\mdfileformat.h"
+#define STORAGE_MAGIC_SIG 0x424A5342 // BSJB
+struct STORAGESIGNATURE
+{
+ ULONG lSignature; // "Magic" signature.
+ USHORT iMajorVer; // Major file version.
+ USHORT iMinorVer; // Minor file version.
+ ULONG iExtraData; // Offset to next structure of information
+ ULONG iVersionString; // Length of version string
+};
+
+void PopulateMetadataRegions()
+{
+ g_metadataRegions.clear();
+
+ // Only populate the metadata regions if core dump
+ if (IsDumpFile())
+ {
+ int numModule;
+ ArrayHolder<DWORD_PTR> moduleList = ModuleFromName(NULL, &numModule);
+ if (moduleList != nullptr)
+ {
+ for (int i = 0; i < numModule; i++)
+ {
+ DacpModuleData moduleData;
+ if (SUCCEEDED(moduleData.Request(g_sos, moduleList[i])))
+ {
+ if (moduleData.metadataStart != 0)
+ {
+ bool add = false;
+ STORAGESIGNATURE header;
+ if (SUCCEEDED(g_ExtData->ReadVirtual(moduleData.metadataStart, (PVOID)&header, sizeof(header), NULL)))
+ {
+ add = header.lSignature != STORAGE_MAGIC_SIG;
+ }
+ else {
+ add = true;
+ }
+ if (add)
+ {
+ MemoryRegion region(moduleData.metadataStart, moduleData.metadataStart + moduleData.metadataSize);
+ g_metadataRegions.insert(region);
+ }
+#ifdef METADATA_REGION_LOGGING
+ ArrayHolder<WCHAR> name = new WCHAR[MAX_LONGPATH];
+ name[0] = '\0';
+ if (moduleData.File != 0)
+ {
+ g_sos->GetPEFileName(moduleData.File, MAX_LONGPATH, name.GetPtr(), NULL);
+ }
+ ExtOut("%c%016x %016x %016x %S\n", add ? '*' : ' ', moduleData.metadataStart, moduleData.metadataStart + moduleData.metadataSize, moduleData.metadataSize, name.GetPtr());
+#endif // METADATA_REGION_LOGGING
+ }
+ }
+ }
+ }
+ }
+}
+
+bool IsMetadataMemory(CLRDATA_ADDRESS address, ULONG32 size)
+{
+ if (!g_metadataRegionsPopulated)
+ {
+ g_metadataRegionsPopulated = true;
+ PopulateMetadataRegions();
+ }
+ MemoryRegion region(address, address + size);
+ const auto& found = g_metadataRegions.find(region);
+ if (found != g_metadataRegions.end())
+ {
+ return found->Contains(region);
+ }
+ return false;
+}
+
+#endif // FEATURE_PAL
\ No newline at end of file
BOOL IsDerivedFrom(CLRDATA_ADDRESS mtObj, __in_z LPCWSTR baseString);
BOOL TryGetMethodDescriptorForDelegate(CLRDATA_ADDRESS delegateAddr, CLRDATA_ADDRESS* pMD);
+#ifdef FEATURE_PAL
+void FlushMetadataRegions();
+bool IsMetadataMemory(CLRDATA_ADDRESS address, ULONG32 size);
+#endif
+
/* Returns a list of all modules in the process.
* Params:
* name - The name of the module you would like. If mName is NULL the all modules are returned.
if (curr_next)
curr_next->Prev = Prev;
}
- }
+ }
};
public:
{
*debugClass = DEBUG_CLASS_USER_WINDOWS;
*qualifier = 0;
+
+ lldb::SBProcess process = GetCurrentProcess();
+ if (process.IsValid())
+ {
+ const char* pluginName = process.GetPluginName();
+ if ((strcmp(pluginName, "elf-core") == 0) || (strcmp(pluginName, "mach-o-core") == 0))
+ {
+ *qualifier = DEBUG_DUMP_FULL;
+ }
+ }
+
return S_OK;
}