зеркало из https://github.com/microsoft/BPerf.git
Update to 5.0 RTM sources
This commit is contained in:
Родитель
b088b8375a
Коммит
2ddd9be429
|
@ -1,4 +1,5 @@
|
|||
cmake_minimum_required (VERSION 3.10)
|
||||
project(bperf)
|
||||
cmake_minimum_required (VERSION 3.10)
|
||||
include_directories(coreclr_headers/src/pal/prebuilt/inc)
|
||||
include_directories(coreclr_headers/src/inc)
|
||||
if(UNIX)
|
||||
|
|
|
@ -709,11 +709,19 @@ RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeRundown, W("EventPipeRundown"), 1, "E
|
|||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeCircularMB, W("EventPipeCircularMB"), 1024, "The EventPipe circular buffer size in megabytes.")
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_EventPipeProcNumbers, W("EventPipeProcNumbers"), 0, "Enable/disable capturing processor numbers in EventPipe event headers")
|
||||
|
||||
//
|
||||
// Generational Aware Analysis
|
||||
//
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisGen, W("GCGenAnalysisGen"), 0, "The generation to trigger generational aware analysis")
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisBytes, W("GCGenAnalysisBytes"), 0, "The number of bytes to trigger generational aware analysis")
|
||||
RETAIL_CONFIG_DWORD_INFO(INTERNAL_GCGenAnalysisIndex, W("GCGenAnalysisIndex"), 0, "The gc index to trigger generational aware analysis")
|
||||
RETAIL_CONFIG_STRING_INFO(INTERNAL_GCGenAnalysisCmd, W("GCGenAnalysisCmd"), "An optional filter to match with the command line used to spawn the process")
|
||||
|
||||
//
|
||||
// Diagnostics Server
|
||||
// Diagnostics Ports
|
||||
//
|
||||
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_DiagnosticsMonitorAddress, W("DOTNET_DiagnosticsMonitorAddress"), "NamedPipe path without '\\\\.\\pipe\\' on Windows; Full path of Unix Domain Socket on Linux/Unix. Used for Diagnostics Monitoring Agents.", CLRConfig::DontPrependCOMPlus_);
|
||||
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_DOTNET_DiagnosticsMonitorPauseOnStart, W("DOTNET_DiagnosticsMonitorPauseOnStart"), 1, "If DOTNET_DiagnosticsMonitorAddress is set, this will cause the runtime to pause during startup. Resume using the Diagnostics IPC ResumeStartup command.", CLRConfig::DontPrependCOMPlus_);
|
||||
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_DOTNET_DefaultDiagnosticPortSuspend, W("DOTNET_DefaultDiagnosticPortSuspend"), 0, "This sets the deafult diagnostic port to suspend causing the runtime to pause during startup before major subsystems are started. Resume using the Diagnostics IPC ResumeStartup command on the default diagnostic port.", CLRConfig::DontPrependCOMPlus_);
|
||||
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_DiagnosticPorts, W("DOTNET_DiagnosticPorts"), "A semicolon delimited list of additional Diagnostic Ports, where a Diagnostic Port is a NamedPipe path without '\\\\.\\pipe\\' on Windows or the full path of Unix Domain Socket on Linux/Unix followed by optional tags, e.g., '<path>,connect,nosuspend;<path>'", CLRConfig::DontPrependCOMPlus_);
|
||||
|
||||
//
|
||||
// LTTng
|
||||
|
|
|
@ -159,6 +159,7 @@ interface ICorDebugReferenceValue;
|
|||
interface ICorDebugHeapValue;
|
||||
interface ICorDebugHeapValue2;
|
||||
interface ICorDebugHeapValue3;
|
||||
interface ICorDebugHeapValue4;
|
||||
interface ICorDebugHandleValue;
|
||||
interface ICorDebugObjectValue;
|
||||
interface ICorDebugStringValue;
|
||||
|
@ -1603,13 +1604,15 @@ typedef enum CorDebugCreateProcessFlags
|
|||
|
||||
|
||||
/* ICorDebugHeapValue::CreateHandle takes a handle flavor.
|
||||
* A strong handle will keep an object alive while a weak track resurrection
|
||||
* will not.
|
||||
* - A strong handle will keep an object alive while allowing GC relocation
|
||||
* - A weak handle will not keep an object alive
|
||||
* - A pinned handle will keep an object alive and disallow GC relocation
|
||||
*/
|
||||
typedef enum CorDebugHandleType
|
||||
{
|
||||
HANDLE_STRONG = 1,
|
||||
HANDLE_WEAK_TRACK_RESURRECTION = 2
|
||||
HANDLE_WEAK_TRACK_RESURRECTION = 2,
|
||||
HANDLE_PINNED = 3
|
||||
} CorDebugHandleType;
|
||||
|
||||
#pragma warning(push)
|
||||
|
@ -3304,6 +3307,9 @@ interface ICorDebugProcess10 : IUnknown
|
|||
// Enable or disable the GC notification events. The GC notification events are turned off by default
|
||||
// They will be delivered through ICorDebugManagedCallback4
|
||||
//
|
||||
// This interface is deprecated. The EnableGCNotificationEvents(true) occasionally deadlocked debug sessions
|
||||
// in .NET Core 5.0 and later. Please use the IID_ICorDebugHeapValue4 to pin an object and prevent its relocation
|
||||
//
|
||||
// Parameters
|
||||
// fEnable - true to enable the events, false to disable
|
||||
//
|
||||
|
@ -6472,6 +6478,27 @@ interface ICorDebugHeapValue3 : IUnknown
|
|||
HRESULT GetMonitorEventWaitList([out] ICorDebugThreadEnum **ppThreadEnum);
|
||||
};
|
||||
|
||||
/*
|
||||
* ICorDebugHeapValue4
|
||||
*/
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(B35DD495-A555-463B-9BE9-C55338486BB8),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface ICorDebugHeapValue4 : IUnknown
|
||||
{
|
||||
|
||||
/*
|
||||
* Creates a handle of the given type for this heap value.
|
||||
*
|
||||
*/
|
||||
HRESULT CreatePinnedHandle([out] ICorDebugHandleValue ** ppHandle);
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* ICorDebugObjectValue is a subclass of ICorDebugValue which applies to
|
||||
* values which contain an object.
|
||||
|
|
|
@ -115,6 +115,8 @@ struct AutoExpVisibleValue
|
|||
template <typename TYPE>
|
||||
class HolderBase
|
||||
{
|
||||
friend class ClrDataAccess;
|
||||
|
||||
protected:
|
||||
TYPE m_value;
|
||||
|
||||
|
@ -227,6 +229,7 @@ template
|
|||
>
|
||||
class BaseHolder : protected BASE
|
||||
{
|
||||
friend class ClrDataAccess;
|
||||
protected:
|
||||
BOOL m_acquired; // Have we acquired the resource?
|
||||
|
||||
|
@ -695,6 +698,7 @@ FORCEINLINE void SafeArrayDoNothing(SAFEARRAY* p)
|
|||
template <typename TYPE, void (*ACQUIREF)(TYPE), void (*RELEASEF)(TYPE)>
|
||||
class FunctionBase : protected HolderBase<TYPE>
|
||||
{
|
||||
friend class ClrDataAccess;
|
||||
protected:
|
||||
|
||||
FORCEINLINE FunctionBase(TYPE value)
|
||||
|
|
|
@ -424,3 +424,17 @@ interface ISOSDacInterface9 : IUnknown
|
|||
{
|
||||
HRESULT GetBreakingChangeVersion(int* pVersion);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
local,
|
||||
uuid(90B8FCC3-7251-4B0A-AE3D-5C13A67EC9AA)
|
||||
]
|
||||
interface ISOSDacInterface10 : IUnknown
|
||||
{
|
||||
HRESULT GetObjectComWrappersData(CLRDATA_ADDRESS objAddr, CLRDATA_ADDRESS *rcw, unsigned int count, CLRDATA_ADDRESS *mowList, unsigned int *pNeeded);
|
||||
HRESULT IsComWrappersCCW(CLRDATA_ADDRESS ccw, BOOL *isComWrappersCCW);
|
||||
HRESULT GetComWrappersCCWData(CLRDATA_ADDRESS ccw, CLRDATA_ADDRESS *managedObject, int *refCount);
|
||||
HRESULT IsComWrappersRCW(CLRDATA_ADDRESS rcw, BOOL *isComWrappersRCW);
|
||||
HRESULT GetComWrappersRCWData(CLRDATA_ADDRESS rcw, CLRDATA_ADDRESS *identity);
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ typedef enum tagEFaultRepRetVal
|
|||
#ifdef __cplusplus
|
||||
#ifndef __PLACEMENT_NEW_INLINE
|
||||
#define __PLACEMENT_NEW_INLINE
|
||||
inline void *__cdecl operator new(long unsigned int, void *_P)
|
||||
inline void *__cdecl operator new(size_t, void *_P)
|
||||
{
|
||||
return (_P);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
|
||||
|
||||
/* File created by MIDL compiler version 8.01.0622 */
|
||||
/* at Mon Jan 18 19:14:07 2038
|
||||
*/
|
||||
/* Compiler settings for runtime/src/coreclr/src/inc/cordebug.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
|
||||
/* Compiler settings for cordebug.idl:
|
||||
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
|
||||
protocol : dce , ms_ext, c_ext, robust
|
||||
error checks: allocation ref bounds_check enum stub_data
|
||||
VC __declspec() decoration level:
|
||||
error checks: allocation ref bounds_check enum stub_data
|
||||
VC __declspec() decoration level:
|
||||
__declspec(uuid()), __declspec(selectany), __declspec(novtable)
|
||||
DECLSPEC_UUID(), MIDL_INTERFACE()
|
||||
*/
|
||||
|
@ -23,7 +21,7 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <rpc.h>
|
||||
|
@ -367,6 +365,9 @@ MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue2,0xE3AC4D6C,0x9CB7,0x43e6,0x96,0xCC
|
|||
MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue3,0xA69ACAD8,0x2374,0x46e9,0x9F,0xF8,0xB1,0xF1,0x41,0x20,0xD2,0x96);
|
||||
|
||||
|
||||
MIDL_DEFINE_GUID(IID, IID_ICorDebugHeapValue4,0xB35DD495,0xA555,0x463B,0x9B,0xE9,0xC5,0x53,0x38,0x48,0x6B,0xB8);
|
||||
|
||||
|
||||
MIDL_DEFINE_GUID(IID, IID_ICorDebugObjectValue,0x18AD3D6E,0xB7D2,0x11d2,0xBD,0x04,0x00,0x00,0xF8,0x08,0x49,0xBD);
|
||||
|
||||
|
||||
|
@ -479,3 +480,6 @@ MIDL_DEFINE_GUID(CLSID, CLSID_EmbeddedCLRCorDebug,0x211f1254,0xbc7e,0x4af5,0xb9,
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef IID CLSID;
|
|||
#endif // CLSID_DEFINED
|
||||
|
||||
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
|
||||
EXTERN_C const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
|
||||
EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
|
||||
|
||||
#endif // !_MIDL_USE_GUIDDEF_
|
||||
|
||||
|
|
|
@ -105,6 +105,10 @@ MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface8,0xc12f35a9,0xe55c,0x4520,0xa8,0x94,0
|
|||
|
||||
MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface9,0x4eca42d8,0x7e7b,0x4c8a,0xa1,0x16,0x7b,0xfb,0xf6,0x92,0x92,0x67);
|
||||
|
||||
|
||||
MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface10,0x90B8FCC3,0x7251,0x4B0A,0xAE,0x3D,0x5C,0x13,0xA6,0x7E,0xC9,0xAA);
|
||||
|
||||
|
||||
#undef MIDL_DEFINE_GUID
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -129,6 +129,20 @@ typedef interface ISOSDacInterface8 ISOSDacInterface8;
|
|||
#endif /* __ISOSDacInterface8_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __ISOSDacInterface9_FWD_DEFINED__
|
||||
#define __ISOSDacInterface9_FWD_DEFINED__
|
||||
typedef interface ISOSDacInterface9 ISOSDacInterface9;
|
||||
|
||||
#endif /* __ISOSDacInterface9_FWD_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __ISOSDacInterface10_FWD_DEFINED__
|
||||
#define __ISOSDacInterface10_FWD_DEFINED__
|
||||
typedef interface ISOSDacInterface10 ISOSDacInterface10;
|
||||
|
||||
#endif /* __ISOSDacInterface10_FWD_DEFINED__ */
|
||||
|
||||
|
||||
/* header files for imported files */
|
||||
#include "unknwn.h"
|
||||
#include "xclrdata.h"
|
||||
|
@ -2745,6 +2759,144 @@ EXTERN_C const IID IID_ISOSDacInterface9;
|
|||
#endif /* __ISOSDacInterface9_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
#ifndef __ISOSDacInterface10_INTERFACE_DEFINED__
|
||||
#define __ISOSDacInterface10_INTERFACE_DEFINED__
|
||||
|
||||
/* interface ISOSDacInterface10 */
|
||||
/* [uuid][local][object] */
|
||||
|
||||
|
||||
EXTERN_C const IID IID_ISOSDacInterface10;
|
||||
|
||||
#if defined(__cplusplus) && !defined(CINTERFACE)
|
||||
|
||||
MIDL_INTERFACE("90B8FCC3-7251-4B0A-AE3D-5C13A67EC9AA")
|
||||
ISOSDacInterface10 : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE GetObjectComWrappersData(
|
||||
CLRDATA_ADDRESS objAddr,
|
||||
CLRDATA_ADDRESS *rcw,
|
||||
unsigned int count,
|
||||
CLRDATA_ADDRESS *mowList,
|
||||
unsigned int *pNeeded) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE IsComWrappersCCW(
|
||||
CLRDATA_ADDRESS ccw,
|
||||
BOOL *isComWrappersCCW) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetComWrappersCCWData(
|
||||
CLRDATA_ADDRESS ccw,
|
||||
CLRDATA_ADDRESS *managedObject,
|
||||
int *refCount) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE IsComWrappersRCW(
|
||||
CLRDATA_ADDRESS rcw,
|
||||
BOOL *isComWrappersRCW) = 0;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetComWrappersRCWData(
|
||||
CLRDATA_ADDRESS rcw,
|
||||
CLRDATA_ADDRESS *identity) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#else /* C style interface */
|
||||
|
||||
typedef struct ISOSDacInterface10Vtbl
|
||||
{
|
||||
BEGIN_INTERFACE
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
|
||||
ISOSDacInterface10 * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
_COM_Outptr_ void **ppvObject);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *AddRef )(
|
||||
ISOSDacInterface10 * This);
|
||||
|
||||
ULONG ( STDMETHODCALLTYPE *Release )(
|
||||
ISOSDacInterface10 * This);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetObjectComWrappersData )(
|
||||
ISOSDacInterface10 * This,
|
||||
CLRDATA_ADDRESS objAddr,
|
||||
CLRDATA_ADDRESS *rcw,
|
||||
unsigned int count,
|
||||
CLRDATA_ADDRESS *mowList,
|
||||
unsigned int *pNeeded);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *IsComWrappersCCW )(
|
||||
ISOSDacInterface10 * This,
|
||||
CLRDATA_ADDRESS ccw,
|
||||
BOOL *isComWrappersCCW);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetComWrappersCCWData )(
|
||||
ISOSDacInterface10 * This,
|
||||
CLRDATA_ADDRESS ccw,
|
||||
CLRDATA_ADDRESS *managedObject,
|
||||
int *refCount);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *IsComWrappersRCW )(
|
||||
ISOSDacInterface10 * This,
|
||||
CLRDATA_ADDRESS rcw,
|
||||
BOOL *isComWrappersRCW);
|
||||
|
||||
HRESULT ( STDMETHODCALLTYPE *GetComWrappersRCWData )(
|
||||
ISOSDacInterface10 * This,
|
||||
CLRDATA_ADDRESS rcw,
|
||||
CLRDATA_ADDRESS *identity);
|
||||
|
||||
END_INTERFACE
|
||||
} ISOSDacInterface10Vtbl;
|
||||
|
||||
interface ISOSDacInterface10
|
||||
{
|
||||
CONST_VTBL struct ISOSDacInterface10Vtbl *lpVtbl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#ifdef COBJMACROS
|
||||
|
||||
|
||||
#define ISOSDacInterface10_QueryInterface(This,riid,ppvObject) \
|
||||
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
|
||||
|
||||
#define ISOSDacInterface10_AddRef(This) \
|
||||
( (This)->lpVtbl -> AddRef(This) )
|
||||
|
||||
#define ISOSDacInterface10_Release(This) \
|
||||
( (This)->lpVtbl -> Release(This) )
|
||||
|
||||
|
||||
#define ISOSDacInterface10_GetObjectComWrappersData(This,objAddr,rcw,count,mowList,pNeeded) \
|
||||
( (This)->lpVtbl -> GetObjectComWrappersData(This,objAddr,rcw,count,mowList,pNeeded) )
|
||||
|
||||
#define ISOSDacInterface10_IsComWrappersCCW(This,ccw,isComWrappersCCW) \
|
||||
( (This)->lpVtbl -> IsComWrappersCCW(This,ccw,isComWrappersCCW) )
|
||||
|
||||
#define ISOSDacInterface10_GetComWrappersCCWData(This,ccw,managedObject,refCount) \
|
||||
( (This)->lpVtbl -> GetComWrappersCCWData(This,ccw,managedObject,refCount) )
|
||||
|
||||
#define ISOSDacInterface10_IsComWrappersRCW(This,rcw,isComWrappersRCW) \
|
||||
( (This)->lpVtbl -> IsComWrappersRCW(This,rcw,isComWrappersRCW) )
|
||||
|
||||
#define ISOSDacInterface10_GetComWrappersRCWData(This,rcw,identity) \
|
||||
( (This)->lpVtbl -> GetComWrappersRCWData(This,rcw,identity) )
|
||||
|
||||
#endif /* COBJMACROS */
|
||||
|
||||
|
||||
#endif /* C style interface */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __ISOSDacInterface10_INTERFACE_DEFINED__ */
|
||||
|
||||
|
||||
/* Additional Prototypes for ALL interfaces */
|
||||
|
||||
/* end of Additional Prototypes */
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#cmakedefine01 HAVE_PTHREAD_NP_H
|
||||
#cmakedefine01 HAVE_AUXV_HWCAP_H
|
||||
#cmakedefine01 HAVE_SYS_PTRACE_H
|
||||
#cmakedefine01 HAVE_GETAUXVAL
|
||||
|
||||
#cmakedefine01 HAVE_KQUEUE
|
||||
#cmakedefine01 HAVE_PTHREAD_SUSPEND
|
||||
|
|
|
@ -47,6 +47,7 @@ check_include_files(numa.h HAVE_NUMA_H)
|
|||
check_include_files(pthread_np.h HAVE_PTHREAD_NP_H)
|
||||
check_include_files("sys/auxv.h;asm/hwcap.h" HAVE_AUXV_HWCAP_H)
|
||||
check_include_files("sys/ptrace.h" HAVE_SYS_PTRACE_H)
|
||||
check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
|
||||
|
@ -1048,8 +1049,6 @@ if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
|
|||
list(INSERT CMAKE_REQUIRED_INCLUDES 0 ${CMAKE_CURRENT_SOURCE_DIR}/libunwind/include ${CMAKE_CURRENT_BINARY_DIR}/libunwind/include)
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "-c -Werror=implicit-function-declaration")
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <libunwind.h>
|
||||
#include <ucontext.h>
|
||||
|
@ -1061,29 +1060,9 @@ int main(int argc, char **argv)
|
|||
return 0;
|
||||
}" UNWIND_CONTEXT_IS_UCONTEXT_T)
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <libunwind.h>
|
||||
check_symbol_exists(unw_get_save_loc libunwind.h HAVE_UNW_GET_SAVE_LOC)
|
||||
check_symbol_exists(unw_get_accessors libunwind.h HAVE_UNW_GET_ACCESSORS)
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
unw_cursor_t cursor;
|
||||
unw_save_loc_t saveLoc;
|
||||
int reg = UNW_REG_IP;
|
||||
unw_get_save_loc(&cursor, reg, &saveLoc);
|
||||
|
||||
return 0;
|
||||
}" HAVE_UNW_GET_SAVE_LOC)
|
||||
|
||||
check_c_source_compiles("
|
||||
#include <libunwind.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
unw_addr_space_t as;
|
||||
unw_get_accessors(as);
|
||||
|
||||
return 0;
|
||||
}" HAVE_UNW_GET_ACCESSORS)
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS)
|
||||
if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
|
||||
list(REMOVE_AT CMAKE_REQUIRED_INCLUDES 0 1)
|
||||
endif()
|
||||
|
|
|
@ -55,6 +55,7 @@ add_library(eventprovider
|
|||
add_library(coreclrtraceptprovider
|
||||
SHARED
|
||||
${TRACEPOINT_PROVIDER_SOURCES}
|
||||
${VERSION_FILE_PATH}
|
||||
)
|
||||
|
||||
add_dependencies(eventprovider generated_eventing_headers)
|
||||
|
|
|
@ -1698,7 +1698,10 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pip, int nee
|
|||
ehFrameHdrLen = ph.p_memsz;
|
||||
break;
|
||||
|
||||
#ifdef PT_ARM_EXIDX
|
||||
#if defined(TARGET_ARM)
|
||||
#ifndef PT_ARM_EXIDX
|
||||
#define PT_ARM_EXIDX 0x70000001 /* See llvm ELF.h */
|
||||
#endif /* !PT_ARM_EXIDX */
|
||||
case PT_ARM_EXIDX:
|
||||
exidxFrameHdrAddr = loadbias + ph.p_vaddr;
|
||||
exidxFrameHdrLen = ph.p_memsz;
|
||||
|
|
|
@ -67,7 +67,7 @@ DWORD SPINLOCKTryAcquire (LONG * lock);
|
|||
// Named mutex
|
||||
|
||||
// Temporarily disabling usage of pthread process-shared mutexes on ARM/ARM64 due to functional issues that cannot easily be
|
||||
// detected with code due to hangs. See https://github.com/dotnet/coreclr/issues/5456.
|
||||
// detected with code due to hangs. See https://github.com/dotnet/runtime/issues/6014.
|
||||
#if HAVE_FULLY_FEATURED_PTHREAD_MUTEXES && HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES && !(defined(HOST_ARM) || defined(HOST_ARM64) || defined(__FreeBSD__))
|
||||
#define NAMED_MUTEX_USE_PTHREAD_MUTEX 1
|
||||
#else
|
||||
|
|
|
@ -91,6 +91,15 @@ int CacheLineSize;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#if HAVE_GETAUXVAL
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace CorUnix;
|
||||
|
@ -125,7 +134,7 @@ static DWORD g_initializeDLLFlags = PAL_INITIALIZE_DLL;
|
|||
static int Initialize(int argc, const char *const argv[], DWORD flags);
|
||||
static BOOL INIT_IncreaseDescriptorLimit(void);
|
||||
static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv);
|
||||
static LPWSTR INIT_ConvertEXEPath(LPCSTR exe_name);
|
||||
static LPWSTR INIT_GetCurrentEXEPath();
|
||||
static BOOL INIT_SharedFilesPath(void);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -560,7 +569,7 @@ Initialize(
|
|||
}
|
||||
|
||||
/* find out the application's full path */
|
||||
exe_path = INIT_ConvertEXEPath(argv[0]);
|
||||
exe_path = INIT_GetCurrentEXEPath();
|
||||
if (NULL == exe_path)
|
||||
{
|
||||
ERROR("Unable to find exe path\n");
|
||||
|
@ -1265,45 +1274,160 @@ static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv)
|
|||
return retval;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
#define symlinkEntrypointExecutable "/proc/self/exe"
|
||||
#elif !defined(__APPLE__)
|
||||
#define symlinkEntrypointExecutable "/proc/curproc/exe"
|
||||
#endif
|
||||
|
||||
bool GetAbsolutePath(const char* path, PathCharString& absolutePath)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
char realPath[PATH_MAX];
|
||||
if (realpath(path, realPath) != nullptr && realPath[0] != '\0')
|
||||
{
|
||||
absolutePath.Set(realPath, strlen(realPath));
|
||||
// realpath should return canonicalized path without the trailing slash
|
||||
_ASSERTE(absolutePath[absolutePath.GetCount() - 1] != '/');
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool GetEntrypointExecutableAbsolutePath(PathCharString& entrypointExecutable)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
entrypointExecutable.Clear();
|
||||
|
||||
// Get path to the executable for the current process using
|
||||
// platform specific means.
|
||||
#if defined(__APPLE__)
|
||||
|
||||
// On Mac, we ask the OS for the absolute path to the entrypoint executable
|
||||
uint32_t lenActualPath = 0;
|
||||
if (_NSGetExecutablePath(nullptr, &lenActualPath) == -1)
|
||||
{
|
||||
// OSX has placed the actual path length in lenActualPath,
|
||||
// so re-attempt the operation
|
||||
PathCharString resizedPath;
|
||||
char *pResizedPath = resizedPath.OpenStringBuffer(lenActualPath);
|
||||
if (_NSGetExecutablePath(pResizedPath, &lenActualPath) == 0)
|
||||
{
|
||||
resizedPath.CloseBuffer(lenActualPath - 1);
|
||||
entrypointExecutable.Set(resizedPath);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
#elif defined (__FreeBSD__)
|
||||
static const int name[] =
|
||||
{
|
||||
CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1
|
||||
};
|
||||
char path[PATH_MAX];
|
||||
size_t len;
|
||||
|
||||
len = sizeof(path);
|
||||
if (sysctl(name, 4, path, &len, nullptr, 0) == 0)
|
||||
{
|
||||
entrypointExecutable.Set(path, len);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ENOMEM
|
||||
result = false;
|
||||
}
|
||||
#elif defined(__NetBSD__) && defined(KERN_PROC_PATHNAME)
|
||||
static const int name[] =
|
||||
{
|
||||
CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
|
||||
};
|
||||
char path[MAXPATHLEN];
|
||||
size_t len;
|
||||
|
||||
len = sizeof(path);
|
||||
if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1)
|
||||
{
|
||||
entrypointExecutable.Set(path, len);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
#elif defined(__sun)
|
||||
const char *path;
|
||||
if ((path = getexecname()) == NULL)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else if (*path != '/')
|
||||
{
|
||||
char *cwd;
|
||||
if ((cwd = getcwd(NULL, PATH_MAX)) == NULL)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
entrypointExecutable.Set(cwd, strlen(cwd));
|
||||
entrypointExecutable.Append('/');
|
||||
entrypointExecutable.Append(path, strlen(path));
|
||||
|
||||
result = true;
|
||||
free(cwd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entrypointExecutable.Set(path, strlen(path));
|
||||
result = true;
|
||||
}
|
||||
#else
|
||||
|
||||
#if HAVE_GETAUXVAL && defined(AT_EXECFN)
|
||||
const char *execfn = (const char *)getauxval(AT_EXECFN);
|
||||
|
||||
if (execfn)
|
||||
{
|
||||
entrypointExecutable.Set(execfn, strlen(execfn));
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// On other OSs, return the symlink that will be resolved by GetAbsolutePath
|
||||
// to fetch the entrypoint EXE absolute path, inclusive of filename.
|
||||
result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable);
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*++
|
||||
Function:
|
||||
INIT_ConvertEXEPath
|
||||
INIT_GetCurrentEXEPath
|
||||
|
||||
Abstract:
|
||||
Check whether the executable path is valid, and convert its type (LPCSTR -> LPWSTR)
|
||||
|
||||
Parameters:
|
||||
LPCSTR exe_name : full path of the current executable
|
||||
Get the current exe path
|
||||
|
||||
Return:
|
||||
pointer to buffer containing the full path. This buffer must be released
|
||||
by the caller using free()
|
||||
|
||||
Notes :
|
||||
this function assumes that "exe_name" is in Unix style (no \)
|
||||
--*/
|
||||
static LPWSTR INIT_ConvertEXEPath(LPCSTR exe_path)
|
||||
static LPWSTR INIT_GetCurrentEXEPath()
|
||||
{
|
||||
PathCharString real_path;
|
||||
LPWSTR return_value;
|
||||
INT return_size;
|
||||
struct stat theStats;
|
||||
|
||||
if (!strchr(exe_path, '/'))
|
||||
if (!GetEntrypointExecutableAbsolutePath(real_path))
|
||||
{
|
||||
ERROR( "The exe path is not fully specified\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (-1 == stat(exe_path, &theStats))
|
||||
{
|
||||
ERROR( "The file does not exist\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!CorUnix::RealPathHelper(exe_path, real_path))
|
||||
{
|
||||
ERROR("realpath() failed!\n");
|
||||
ERROR( "Cannot get current exe path\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ Abstract:
|
|||
#include "pal/dbgmsg.h"
|
||||
SET_DEFAULT_DEBUG_CHANNEL(MISC);
|
||||
#include "pal/palinternal.h"
|
||||
#include <limits>
|
||||
#include <limits.h>
|
||||
#include <sys/resource.h>
|
||||
#include "pal/virtual.h"
|
||||
|
@ -53,8 +54,8 @@ public:
|
|||
static void Initialize()
|
||||
{
|
||||
s_cgroup_version = FindCGroupVersion();
|
||||
s_memory_cgroup_path = FindCGroupPath(&IsCGroup1MemorySubsystem);
|
||||
s_cpu_cgroup_path = FindCGroupPath(&IsCGroup1CpuSubsystem);
|
||||
s_memory_cgroup_path = FindCGroupPath(s_cgroup_version == 1 ? &IsCGroup1MemorySubsystem : nullptr);
|
||||
s_cpu_cgroup_path = FindCGroupPath(s_cgroup_version == 1 ? &IsCGroup1CpuSubsystem : nullptr);
|
||||
}
|
||||
|
||||
static void Cleanup()
|
||||
|
@ -245,33 +246,37 @@ private:
|
|||
|
||||
if (strncmp(filesystemType, "cgroup", 6) == 0)
|
||||
{
|
||||
char* context = nullptr;
|
||||
char* strTok = strtok_s(options, ",", &context);
|
||||
while (strTok != nullptr)
|
||||
bool isSubsystemMatch = is_subsystem == nullptr;
|
||||
if (!isSubsystemMatch)
|
||||
{
|
||||
if (is_subsystem(strTok))
|
||||
char* context = nullptr;
|
||||
char* strTok = strtok_s(options, ",", &context);
|
||||
while (!isSubsystemMatch && strTok != nullptr)
|
||||
{
|
||||
mountpath = (char*)PAL_malloc(lineLen+1);
|
||||
if (mountpath == nullptr)
|
||||
goto done;
|
||||
mountroot = (char*)PAL_malloc(lineLen+1);
|
||||
if (mountroot == nullptr)
|
||||
goto done;
|
||||
|
||||
sscanfRet = sscanf_s(line,
|
||||
"%*s %*s %*s %s %s ",
|
||||
mountroot, lineLen+1,
|
||||
mountpath, lineLen+1);
|
||||
if (sscanfRet != 2)
|
||||
_ASSERTE(!"Failed to parse mount info file contents with sscanf_s.");
|
||||
|
||||
// assign the output arguments and clear the locals so we don't free them.
|
||||
*pmountpath = mountpath;
|
||||
*pmountroot = mountroot;
|
||||
mountpath = mountroot = nullptr;
|
||||
goto done;
|
||||
isSubsystemMatch = is_subsystem(strTok);
|
||||
strTok = strtok_s(nullptr, ",", &context);
|
||||
}
|
||||
strTok = strtok_s(nullptr, ",", &context);
|
||||
}
|
||||
if (isSubsystemMatch)
|
||||
{
|
||||
mountpath = (char*)PAL_malloc(lineLen+1);
|
||||
if (mountpath == nullptr)
|
||||
goto done;
|
||||
mountroot = (char*)PAL_malloc(lineLen+1);
|
||||
if (mountroot == nullptr)
|
||||
goto done;
|
||||
|
||||
sscanfRet = sscanf_s(line,
|
||||
"%*s %*s %*s %s %s ",
|
||||
mountroot, lineLen+1,
|
||||
mountpath, lineLen+1);
|
||||
if (sscanfRet != 2)
|
||||
_ASSERTE(!"Failed to parse mount info file contents with sscanf_s.");
|
||||
|
||||
// assign the output arguments and clear the locals so we don't free them.
|
||||
*pmountpath = mountpath;
|
||||
*pmountroot = mountroot;
|
||||
mountpath = mountroot = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,7 +348,7 @@ private:
|
|||
// See https://www.kernel.org/doc/Documentation/cgroup-v2.txt
|
||||
// Look for a "0::/some/path"
|
||||
int sscanfRet = sscanf_s(line,
|
||||
"0::%s", lineLen+1,
|
||||
"0::%s",
|
||||
cgroup_path, lineLen+1);
|
||||
if (sscanfRet == 1)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,135 @@ SET_DEFAULT_DEBUG_CHANNEL(MISC);
|
|||
#include <asm/hwcap.h>
|
||||
#endif
|
||||
|
||||
#if defined(HOST_ARM64) && defined(__linux__)
|
||||
struct CpuCapability
|
||||
{
|
||||
const char* name;
|
||||
unsigned long hwCapFlag;
|
||||
};
|
||||
|
||||
static const CpuCapability CpuCapabilities[] = {
|
||||
//{ "fp", HWCAP_FP },
|
||||
#ifdef HWCAP_ASIMD
|
||||
{ "asimd", HWCAP_ASIMD },
|
||||
#endif
|
||||
//{ "evtstrm", HWCAP_EVTSTRM },
|
||||
#ifdef HWCAP_AES
|
||||
{ "aes", HWCAP_AES },
|
||||
#endif
|
||||
//{ "pmull", HWCAP_PMULL },
|
||||
#ifdef HWCAP_SHA1
|
||||
{ "sha1", HWCAP_SHA1 },
|
||||
#endif
|
||||
#ifdef HWCAP_SHA2
|
||||
{ "sha2", HWCAP_SHA2 },
|
||||
#endif
|
||||
#ifdef HWCAP_CRC32
|
||||
{ "crc32", HWCAP_CRC32 },
|
||||
#endif
|
||||
#ifdef HWCAP_ATOMICS
|
||||
{ "atomics", HWCAP_ATOMICS },
|
||||
#endif
|
||||
//{ "fphp", HWCAP_FPHP },
|
||||
//{ "asimdhp", HWCAP_ASIMDHP },
|
||||
//{ "cpuid", HWCAP_CPUID },
|
||||
#ifdef HWCAP_ASIMDRDM
|
||||
{ "asimdrdm", HWCAP_ASIMDRDM },
|
||||
#endif
|
||||
//{ "jscvt", HWCAP_JSCVT },
|
||||
//{ "fcma", HWCAP_FCMA },
|
||||
//{ "lrcpc", HWCAP_LRCPC },
|
||||
//{ "dcpop", HWCAP_DCPOP },
|
||||
//{ "sha3", HWCAP_SHA3 },
|
||||
//{ "sm3", HWCAP_SM3 },
|
||||
//{ "sm4", HWCAP_SM4 },
|
||||
#ifdef HWCAP_ASIMDDP
|
||||
{ "asimddp", HWCAP_ASIMDDP },
|
||||
#endif
|
||||
//{ "sha512", HWCAP_SHA512 },
|
||||
//{ "sve", HWCAP_SVE },
|
||||
//{ "asimdfhm", HWCAP_ASIMDFHM },
|
||||
//{ "dit", HWCAP_DIT },
|
||||
//{ "uscat", HWCAP_USCAT },
|
||||
//{ "ilrcpc", HWCAP_ILRCPC },
|
||||
//{ "flagm", HWCAP_FLAGM },
|
||||
//{ "ssbs", HWCAP_SSBS },
|
||||
//{ "sb", HWCAP_SB },
|
||||
//{ "paca", HWCAP_PACA },
|
||||
//{ "pacg", HWCAP_PACG },
|
||||
|
||||
// Ensure the array is never empty
|
||||
{ "", 0 }
|
||||
};
|
||||
|
||||
// Returns the HWCAP_* flag corresponding to the given capability name.
|
||||
// If the capability name is not recognized or unused at present, zero is returned.
|
||||
static unsigned long LookupCpuCapabilityFlag(const char* start, size_t length)
|
||||
{
|
||||
for (int i = 0; i < _countof(CpuCapabilities); i++)
|
||||
{
|
||||
const char* capabilityName = CpuCapabilities[i].name;
|
||||
if ((length == strlen(capabilityName)) && (memcmp(start, capabilityName, length) == 0))
|
||||
{
|
||||
return CpuCapabilities[i].hwCapFlag;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Reads the first Features entry from /proc/cpuinfo (assuming other entries are essentially
|
||||
// identical) and translates it into a set of HWCAP_* flags.
|
||||
static unsigned long GetCpuCapabilityFlagsFromCpuInfo()
|
||||
{
|
||||
unsigned long capabilityFlags = 0;
|
||||
FILE* cpuInfoFile = fopen("/proc/cpuinfo", "r");
|
||||
|
||||
if (cpuInfoFile != NULL)
|
||||
{
|
||||
char* line = nullptr;
|
||||
size_t lineLen = 0;
|
||||
|
||||
while (getline(&line, &lineLen, cpuInfoFile) != -1)
|
||||
{
|
||||
char* p = line;
|
||||
while (isspace(*p)) p++;
|
||||
|
||||
if (memcmp(p, "Features", 8) != 0)
|
||||
continue;
|
||||
|
||||
// Skip "Features" and look for ':'
|
||||
p += 8;
|
||||
|
||||
while (isspace(*p)) p++;
|
||||
if (*p != ':')
|
||||
continue;
|
||||
|
||||
// Skip ':' and parse the list
|
||||
p++;
|
||||
|
||||
while (true)
|
||||
{
|
||||
while (isspace(*p)) p++;
|
||||
if (*p == 0)
|
||||
break;
|
||||
|
||||
char* start = p++;
|
||||
while ((*p != 0) && !isspace(*p)) p++;
|
||||
|
||||
capabilityFlags |= LookupCpuCapabilityFlag(start, p - start);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
free(line);
|
||||
fclose(cpuInfoFile);
|
||||
}
|
||||
|
||||
return capabilityFlags;
|
||||
}
|
||||
#endif // defined(HOST_ARM64) && defined(__linux__)
|
||||
|
||||
PALIMPORT
|
||||
VOID
|
||||
PALAPI
|
||||
|
@ -26,6 +155,13 @@ PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags)
|
|||
#if HAVE_AUXV_HWCAP_H
|
||||
unsigned long hwCap = getauxval(AT_HWCAP);
|
||||
|
||||
#if defined(__linux__)
|
||||
// getauxval(AT_HWCAP) returns zero on WSL1 (https://github.com/microsoft/WSL/issues/3682),
|
||||
// fall back to reading capabilities from /proc/cpuinfo.
|
||||
if (hwCap == 0)
|
||||
hwCap = GetCpuCapabilityFlagsFromCpuInfo();
|
||||
#endif
|
||||
|
||||
// HWCAP_* flags are introduced by ARM into the Linux kernel as new extensions are published.
|
||||
// For a given kernel, some of these flags may not be present yet.
|
||||
// Use ifdef for each to allow for compilation with any vintage kernel.
|
||||
|
|
|
@ -565,9 +565,14 @@ PAL_GetLogicalProcessorCacheSizeFromOS()
|
|||
cacheSize = std::max(cacheSize, (size_t)sysconf(_SC_LEVEL4_CACHE_SIZE));
|
||||
#endif
|
||||
|
||||
#if defined(HOST_ARM64)
|
||||
if(cacheSize == 0)
|
||||
#if defined(TARGET_LINUX) && !defined(HOST_ARM)
|
||||
if (cacheSize == 0)
|
||||
{
|
||||
//
|
||||
// Fallback to retrieve cachesize via /sys/.. if sysconf was not available
|
||||
// for the platform. Currently musl and arm64 should be only cases to use
|
||||
// this method to determine cache size.
|
||||
//
|
||||
size_t size;
|
||||
|
||||
if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index0/size", &size))
|
||||
|
@ -581,8 +586,10 @@ PAL_GetLogicalProcessorCacheSizeFromOS()
|
|||
if(ReadMemoryValueFromFile("/sys/devices/system/cpu/cpu0/cache/index4/size", &size))
|
||||
cacheSize = std::max(cacheSize, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(cacheSize == 0)
|
||||
#if defined(HOST_ARM64)
|
||||
if (cacheSize == 0)
|
||||
{
|
||||
// It is currently expected to be missing cache size info
|
||||
//
|
||||
|
|
|
@ -80,6 +80,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PROCESS); // some headers have code with asserts, so d
|
|||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <libproc.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/posix_sem.h>
|
||||
#endif
|
||||
|
@ -3005,65 +3006,63 @@ CreateProcessModules(
|
|||
|
||||
// NOTE: the module path can have spaces in the name
|
||||
// __TEXT 0000000196220000-00000001965b4000 [ 3664K 2340K 0K 0K] r-x/rwx SM=COW /Volumes/Builds/builds/devmain/rawproduct/debug/build/out/Applications/Microsoft Excel.app/Contents/SharedSupport/PowerQuery/libcoreclr.dylib
|
||||
char *line = NULL;
|
||||
size_t lineLen = 0;
|
||||
|
||||
// NOTE: Sometimes vmmap hides full paths to some process modules (.dylibs in non-system folders), causing debugger not to work.
|
||||
// __TEXT 000000010d8bd000-000000010ddce000 [ 5188K 5188K 0K 0K] r-x/rwx SM=COW /Users/USER/*/libcoreclr.dylib
|
||||
// So now we get modules information by iterating over regions using proc_pidinfo(). See dotnet/runtime#42888.
|
||||
int count = 0;
|
||||
ssize_t read;
|
||||
|
||||
char vmmapCommand[100];
|
||||
int chars = snprintf(vmmapCommand, sizeof(vmmapCommand), "/usr/bin/vmmap -interleaved %d -wide", dwProcessId);
|
||||
_ASSERTE(chars > 0 && chars <= sizeof(vmmapCommand));
|
||||
|
||||
FILE *vmmapFile = popen(vmmapCommand, "r");
|
||||
if (vmmapFile == NULL)
|
||||
uint64_t addr = 0;
|
||||
while (true)
|
||||
{
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Reading maps file line by line
|
||||
while ((read = getline(&line, &lineLen, vmmapFile)) != -1)
|
||||
{
|
||||
void *startAddress, *endAddress;
|
||||
char moduleName[PATH_MAX];
|
||||
|
||||
if (sscanf_s(line, "__TEXT %p-%p [ %*[0-9K ]] %*[-/rwxsp] SM=%*[A-Z] %[^\n]", &startAddress, &endAddress, moduleName, _countof(moduleName)) == 3)
|
||||
struct proc_regionwithpathinfo rwpi;
|
||||
int sz = proc_pidinfo(dwProcessId, PROC_PIDREGIONPATHINFO, addr, &rwpi, sizeof rwpi);
|
||||
if (sz != sizeof rwpi)
|
||||
{
|
||||
bool dup = false;
|
||||
for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
|
||||
{
|
||||
if (strcmp(moduleName, entry->Name) == 0)
|
||||
{
|
||||
dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sz == 0 && errno == EINVAL)
|
||||
break; // ok
|
||||
|
||||
if (!dup)
|
||||
DestroyProcessModules(listHead);
|
||||
listHead = NULL;
|
||||
count = 0;
|
||||
break; // unknown error
|
||||
}
|
||||
|
||||
const char *moduleName = rwpi.prp_vip.vip_path;
|
||||
|
||||
bool dup = false;
|
||||
for (ProcessModules *entry = listHead; entry != NULL; entry = entry->Next)
|
||||
{
|
||||
if (strcmp(moduleName, entry->Name) == 0)
|
||||
{
|
||||
int cbModuleName = strlen(moduleName) + 1;
|
||||
ProcessModules *entry = (ProcessModules *)InternalMalloc(sizeof(ProcessModules) + cbModuleName);
|
||||
if (entry == NULL)
|
||||
{
|
||||
DestroyProcessModules(listHead);
|
||||
listHead = NULL;
|
||||
count = 0;
|
||||
break;
|
||||
}
|
||||
strcpy_s(entry->Name, cbModuleName, moduleName);
|
||||
entry->BaseAddress = startAddress;
|
||||
entry->Next = listHead;
|
||||
listHead = entry;
|
||||
count++;
|
||||
dup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dup)
|
||||
{
|
||||
int cbModuleName = strlen(moduleName) + 1;
|
||||
ProcessModules *entry = (ProcessModules *)InternalMalloc(sizeof(ProcessModules) + cbModuleName);
|
||||
if (entry == NULL)
|
||||
{
|
||||
DestroyProcessModules(listHead);
|
||||
listHead = NULL;
|
||||
count = 0;
|
||||
break; // no memory
|
||||
}
|
||||
memcpy_s(entry->Name, cbModuleName, moduleName, cbModuleName);
|
||||
entry->BaseAddress = (void *)rwpi.prp_prinfo.pri_address;
|
||||
entry->Next = listHead;
|
||||
listHead = entry;
|
||||
count++;
|
||||
}
|
||||
|
||||
addr = rwpi.prp_prinfo.pri_address + rwpi.prp_prinfo.pri_size;
|
||||
}
|
||||
|
||||
*lpCount = count;
|
||||
|
||||
free(line); // We didn't allocate line, but as per contract of getline we should free it
|
||||
pclose(vmmapFile);
|
||||
exit:
|
||||
|
||||
#elif HAVE_PROCFS_MAPS
|
||||
|
||||
// Here we read /proc/<pid>/maps file in order to parse it and figure out what it says
|
||||
|
|
|
@ -48,4 +48,4 @@ This test case should be run manually. Requires user input.
|
|||
|
||||
filemapping_memmgt\MapViewOfFile\test1
|
||||
=======================================
|
||||
Refer this github issue https://github.com/dotnet/coreclr/issues/5176
|
||||
Refer this github issue https://github.com/dotnet/runtime/issues/5924
|
||||
|
|
|
@ -841,7 +841,7 @@ DWORD AbandonTests_Child_AbruptExit(void *arg = nullptr)
|
|||
|
||||
// This child process acquires the mutex lock, creates another child process (to ensure that file locks are not inherited), and
|
||||
// abandons the mutex abruptly. The second child process detects the abandonment and abandons the mutex again for the parent to
|
||||
// detect. Issue: https://github.com/dotnet/coreclr/issues/21455
|
||||
// detect. Issue: https://github.com/dotnet/runtime/issues/11636
|
||||
DWORD AbandonTests_Child_FileLocksNotInherited_Parent_AbruptExit(void *arg = nullptr)
|
||||
{
|
||||
const char *testName = "AbandonTests";
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
${NM:-nm} -P -t x $1 | awk -F ' ' '/g_dacTable/ { print "#define DAC_TABLE_RVA 0x" substr("0000000000000000" $3, length($3) + 1); exit }' > $2
|
||||
if [ "$1" = "--dynamic" ]; then
|
||||
__DynamicSymbolsOption="-D"
|
||||
shift
|
||||
else
|
||||
__DynamicSymbolsOption=""
|
||||
fi
|
||||
${NM:-nm} $__DynamicSymbolsOption -P -t x $1 | awk -F ' ' '/g_dacTable/ { print "#define DAC_TABLE_RVA 0x" substr("0000000000000000" $3, length($3) + 1); exit }' > $2
|
||||
|
|
Загрузка…
Ссылка в новой задаче