Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions docs/design/datacontracts/StressLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Data descriptors used:
| StressLog | TickFrequency | Number of ticks per second for stresslog timestamps |
| StressLog | StartTimestamp | Timestamp when the stress log was started |
| StressLog | ModuleOffset | Offset of the module in the stress log |
| StressLog | Modules | Offset of the stress log's module table (if StressLogHasModuleTable is `1`) |
| StressLog | Logs | Pointer to the thread-specific logs |
| StressLogModuleDesc | BaseAddress | Base address of the module |
| StressLogModuleDesc | Size | Size of the module |
Expand Down Expand Up @@ -80,7 +81,6 @@ Global variables used:
| StressLogChunkSize | uint | Size of a stress log chunk |
| StressLogMaxMessageSize | ulong | Maximum size of a stress log message |
| StressLogHasModuleTable | byte | Whether the stress log module table is present |
| StressLogModuleTable | pointer | Pointer to the stress log's module table (if StressLogHasModuleTable is `1`) |

```csharp
bool HasStressLog()
Expand Down Expand Up @@ -216,12 +216,21 @@ protected TargetPointer GetFormatPointer(ulong formatOffset)
return new TargetPointer(stressLog.ModuleOffset + formatOffset);
}

TargetPointer moduleTable = target.ReadGlobalPointer(Constants.Globals.StressLogModuleTable);
TargetPointer? moduleTable;
Comment thread
davidwrighton marked this conversation as resolved.
if (!target.TryReadGlobalPointer(Constants.Globals.StressLogModuleTable, out moduleTable))
{
if (!target.TryReadGlobalPointer(Constants.Globals.StressLog, out TargetPointer? pStressLog))
{
throw new InvalidOperationException("StressLogModuleTable is not set and StressLog is not available, but StressLogHasModuleTable is set to 1.");
}
Data.StressLog stressLog = target.ProcessedData.GetOrAdd<Data.StressLog>(pStressLog.Value);
moduleTable = stressLog.Modules ?? throw new InvalidOperationException("StressLogModuleTable is not set and StressLog does not contain a ModuleTable offset, but StressLogHasModuleTable is set to 1.");
}
uint moduleEntrySize = target.GetTypeInfo(DataType.StressLogModuleDesc).Size!.Value;
uint maxModules = target.ReadGlobal<uint>(Constants.Globals.StressLogMaxModules);
for (uint i = 0; i < maxModules; ++i)
{
StressLogModuleDesc module = new(Target, moduleTable + i * moduleEntrySize);
StressLogModuleDesc module = new(Target, moduleTable.Value + i * moduleEntrySize);
ulong relativeOffset = formatOffset - cumulativeOffset;
if (relativeOffset < module.Size.Value)
{
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/clrdatadescriptors.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,13 @@ function(generate_data_descriptors)

# inherit definitions, include directories, and dependencies from the INTERFACE target
target_link_libraries(${LIBRARY} PRIVATE ${DATA_DESCRIPTORS_INTERFACE_TARGET})

if(MSVC)
# /Zc:externConstexpr is required to export constexpr variables
# from the object file, otherwise the linker will not export them.
# See https://learn.microsoft.com/en-us/cpp/build/reference/zc-externconstexpr
# for more details.
target_compile_options(${LIBRARY} PRIVATE /Zc:externConstexpr)
endif(MSVC)
endif()
endfunction(generate_data_descriptors)
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ struct ContractDescriptor
const char *descriptor;
const uint32_t pointer_data_count;
uint32_t pad0;
const uintptr_t *pointer_data;
const void** pointer_data;
};

// POINTER_DATA_NAME and CONTRACT_NAME are macros provided by
// contractconfiguration.h which is configured by CMake
extern const uintptr_t POINTER_DATA_NAME[];
extern const void* POINTER_DATA_NAME[];

#if EXPORT_CONTRACT
DLLEXPORT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ struct ContractDescriptor
const char *descriptor;
const uint32_t pointer_data_count;
uint32_t pad0;
const uintptr_t *pointer_data;
const void** pointer_data;
};

// POINTER_DATA_NAME and CONTRACT_NAME are macros provided by
// contractconfiguration.h which is configured by CMake
extern const uintptr_t POINTER_DATA_NAME[];
extern const void* POINTER_DATA_NAME[];

// just the placeholder pointer
const uintptr_t POINTER_DATA_NAME[] = { (uintptr_t)0 };
const void* POINTER_DATA_NAME[] = { (void*)0 };

DLLEXPORT struct ContractDescriptor CONTRACT_NAME;

Expand Down
17 changes: 8 additions & 9 deletions src/coreclr/debug/datadescriptor-shared/contractpointerdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@

extern "C"
{
// without an extern declaration, clang does not emit this global into the object file
extern const uintptr_t POINTER_DATA_NAME[];

const uintptr_t POINTER_DATA_NAME[] = {
(uintptr_t)0, // placeholder
#define CDAC_GLOBAL_POINTER(name,value) (uintptr_t)(value),
#define CDAC_GLOBAL_SUB_DESCRIPTOR(name,value) (uintptr_t)(value),
#include "wrappeddatadescriptor.inc"
// without an extern declaration, clang does not emit this global into the object file
extern constexpr const void* POINTER_DATA_NAME[] = {
(void*)0, // placeholder
#define CDAC_GLOBAL_POINTER(name,value) (void*)(value),
#define CDAC_GLOBAL_SUB_DESCRIPTOR(name,value) (void*)(value),
#include "wrappeddatadescriptor.inc"
};
};
}

27 changes: 14 additions & 13 deletions src/coreclr/inc/stresslog.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,23 +396,24 @@ inline BOOL StressLog::LogOn(unsigned facility, unsigned level)
template<>
struct cdac_offsets<StressLog>
{
static const size_t facilitiesToLog = offsetof(StressLog, facilitiesToLog);
static const size_t levelToLog = offsetof(StressLog, levelToLog);
static const size_t MaxSizePerThread = offsetof(StressLog, MaxSizePerThread);
static const size_t MaxSizeTotal = offsetof(StressLog, MaxSizeTotal);
static const size_t totalChunk = offsetof(StressLog, totalChunk);
static const size_t logs = offsetof(StressLog, logs);
static const size_t tickFrequency = offsetof(StressLog, tickFrequency);
static const size_t startTimeStamp = offsetof(StressLog, startTimeStamp);
static const size_t startTime = offsetof(StressLog, startTime);
static const size_t moduleOffset = offsetof(StressLog, moduleOffset);
static constexpr uint64_t MAX_MODULES = StressLog::MAX_MODULES;
static constexpr size_t facilitiesToLog = offsetof(StressLog, facilitiesToLog);
static constexpr size_t levelToLog = offsetof(StressLog, levelToLog);
static constexpr size_t MaxSizePerThread = offsetof(StressLog, MaxSizePerThread);
static constexpr size_t MaxSizeTotal = offsetof(StressLog, MaxSizeTotal);
static constexpr size_t totalChunk = offsetof(StressLog, totalChunk);
static constexpr size_t logs = offsetof(StressLog, logs);
static constexpr size_t tickFrequency = offsetof(StressLog, tickFrequency);
static constexpr size_t startTimeStamp = offsetof(StressLog, startTimeStamp);
static constexpr size_t startTime = offsetof(StressLog, startTime);
static constexpr size_t moduleOffset = offsetof(StressLog, moduleOffset);
static constexpr size_t MAX_MODULES = StressLog::MAX_MODULES;
static constexpr size_t modules = offsetof(StressLog, modules);

struct ModuleDesc
{
static constexpr size_t type_size = sizeof(StressLog::ModuleDesc);
static const size_t baseAddress = offsetof(StressLog::ModuleDesc, baseAddress);
static const size_t size = offsetof(StressLog::ModuleDesc, size);
static constexpr size_t baseAddress = offsetof(StressLog::ModuleDesc, baseAddress);
static constexpr size_t size = offsetof(StressLog::ModuleDesc, size);
};
};

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/datadescriptor/datadescriptor.inc
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ CDAC_TYPE_FIELD(StressLog, /* pointer */, Logs, cdac_offsets<StressLog>::logs)
CDAC_TYPE_FIELD(StressLog, /* uint64 */, TickFrequency, cdac_offsets<StressLog>::tickFrequency)
CDAC_TYPE_FIELD(StressLog, /* uint64 */, StartTimestamp, cdac_offsets<StressLog>::startTimeStamp)
CDAC_TYPE_FIELD(StressLog, /* nuint */, ModuleOffset, cdac_offsets<StressLog>::moduleOffset)
CDAC_TYPE_FIELD(StressLog, /* StressLogModuleDesc[] */, Modules, cdac_offsets<StressLog>::modules)
CDAC_TYPE_END(StressLog)

CDAC_TYPE_BEGIN(StressLogModuleDesc)
Expand Down Expand Up @@ -908,7 +909,6 @@ CDAC_GLOBAL_POINTER(TlsIndexBase, &::_tls_index)
CDAC_GLOBAL(StressLogEnabled, uint8, 1)
CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog)
CDAC_GLOBAL(StressLogHasModuleTable, uint8, 1)
CDAC_GLOBAL_POINTER(StressLogModuleTable, &g_pStressLog->modules)
CDAC_GLOBAL(StressLogMaxModules, uint64, cdac_offsets<StressLog>::MAX_MODULES)
CDAC_GLOBAL(StressLogChunkSize, uint32, STRESSLOG_CHUNK_SIZE)
CDAC_GLOBAL(StressLogValidChunkSig, uint32, StressLogChunk::ValidChunkSig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,22 @@ private TargetPointer GetFormatPointer(ulong formatOffset)
return new TargetPointer(stressLog.ModuleOffset.Value + formatOffset);
}

TargetPointer moduleTable = target.ReadGlobalPointer(Constants.Globals.StressLogModuleTable);
TargetPointer? moduleTable;
if (!target.TryReadGlobalPointer(Constants.Globals.StressLogModuleTable, out moduleTable))
{
if (!target.TryReadGlobalPointer(Constants.Globals.StressLog, out TargetPointer? pStressLog))
{
throw new InvalidOperationException("StressLogModuleTable is not set and StressLog is not available, but StressLogHasModuleTable is set to 1.");
}
Data.StressLog stressLog = target.ProcessedData.GetOrAdd<Data.StressLog>(pStressLog.Value);
moduleTable = stressLog.Modules ?? throw new InvalidOperationException("StressLogModuleTable is not set and StressLog does not contain a ModuleTable offset, but StressLogHasModuleTable is set to 1.");
}
uint moduleEntrySize = target.GetTypeInfo(DataType.StressLogModuleDesc).Size!.Value;
uint maxModules = target.ReadGlobal<uint>(Constants.Globals.StressLogMaxModules);
ulong cumulativeOffset = 0;
for (uint i = 0; i < maxModules; ++i)
{
Data.StressLogModuleDesc module = target.ProcessedData.GetOrAdd<Data.StressLogModuleDesc>(moduleTable + i * moduleEntrySize);
Data.StressLogModuleDesc module = target.ProcessedData.GetOrAdd<Data.StressLogModuleDesc>(moduleTable.Value + i * moduleEntrySize);
ulong relativeOffset = formatOffset - cumulativeOffset;
if (relativeOffset < module.Size.Value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public StressLog(Target target, TargetPointer address)
StartTimestamp = target.Read<ulong>(address + (ulong)type.Fields[nameof(StartTimestamp)].Offset);
ModuleOffset = target.ReadNUInt(address + (ulong)type.Fields[nameof(ModuleOffset)].Offset);

if (type.Fields.ContainsKey(nameof(Modules)))
Modules = target.ReadPointer(address + (ulong)type.Fields[nameof(Modules)].Offset);

Logs = target.ReadPointer(address + (ulong)type.Fields[nameof(Logs)].Offset);
}

Expand All @@ -42,5 +45,7 @@ public StressLog(Target target, TargetPointer address)

public TargetNUInt ModuleOffset { get; init; }

public TargetPointer? Modules { get; init; }

public TargetPointer Logs { get; init; }
}
5 changes: 3 additions & 2 deletions src/tools/StressLogAnalyzer/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ private static ContractDescriptorParser.ContractDescriptor GetDescriptor(int str
{
Baseline = BaseContractDescriptor.Baseline,
Version = BaseContractDescriptor.Version,
Contracts = new(){ { "StressLog", stressLogVersion } },
Contracts = new() { { "StressLog", stressLogVersion } },
Types = BaseContractDescriptor.Types,
Globals = BaseContractDescriptor.Globals,
};
Expand All @@ -542,7 +542,8 @@ private static ContractDescriptorParser.ContractDescriptor GetDescriptor(int str
"Logs": 24,
"TickFrequency": 48,
"StartTimestamp": 56,
"ModuleOffset": 72
"ModuleOffset": 72,
"Modules": 80
},
"StressLogModuleDesc": {
"!": 16,
Expand Down
Loading