#******************************************************************
"""
+specialCaseSizes = { "BulkType" : { "Values" : "Values_ElementSize" }, "GCBulkRootCCW" : { "Values" : "Values_ElementSize" }, "GCBulkRCW" : { "Values" : "Values_ElementSize" }, "GCBulkRootStaticVar" : { "Values" : "Values_ElementSize" } }
+
lttngDataTypeMapping ={
#constructed types
"win:null" :" ",
bool success = true;
""" % (template.estimated_size, template.estimated_size)
footer = """
- if (!fixedBuffer)
- delete[] buffer;
+ if (!fixedBuffer)
+ delete[] buffer;
"""
+
pack_list = []
for paramName in fnSig.paramlist:
parameter = fnSig.getParam(paramName)
if paramName in template.structs:
- pack_list.append(" success &= WriteToBuffer((const BYTE *)%s, (int)%s_ElementSize * (int)%s, buffer, offset, size, fixedBuffer);" % (paramName, paramName, parameter.prop))
+ size = "(int)%s_ElementSize * (int)%s" % (paramName, parameter.prop)
+ if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
+ size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
+ pack_list.append(" success &= WriteToBuffer((const BYTE *)%s, %s, buffer, offset, size, fixedBuffer);" % (paramName, size))
elif paramName in template.arrays:
- pack_list.append(" success &= WriteToBuffer((const BYTE *)%s, sizeof(%s) * (int)%s, buffer, offset, size, fixedBuffer);" % (paramName, lttngDataTypeMapping[parameter.winType], parameter.prop))
+ size = "sizeof(%s) * (int)%s" % (lttngDataTypeMapping[parameter.winType], parameter.prop)
+ if template.name in specialCaseSizes and paramName in specialCaseSizes[template.name]:
+ size = "(int)(%s)" % specialCaseSizes[template.name][paramName]
+ pack_list.append(" success &= WriteToBuffer((const BYTE *)%s, %s, buffer, offset, size, fixedBuffer);" % (paramName, size))
elif parameter.winType == "win:GUID":
pack_list.append(" success &= WriteToBuffer(*%s, buffer, offset, size, fixedBuffer);" % (parameter.name,))
else:
if __name__ == '__main__':
return_code = main(sys.argv[1:])
- sys.exit(return_code)
+ sys.exit(return_code)
\ No newline at end of file
EventDataDescCreate(&eventData[2], m_etwRcwData, sizeof(EventRCWEntry) * m_currRcw);
ULONG result = EventWrite(Microsoft_Windows_DotNETRuntimeHandle, &GCBulkRCW, _countof(eventData), eventData);
- _ASSERTE(result == ERROR_SUCCESS);
#else
-// UNIXTODO: "Eventing Not Implemented"
+ ULONG result = FireEtXplatGCBulkRCW(m_currRcw, instance, sizeof(EventRCWEntry) * m_currRcw, m_etwRcwData);
#endif // !defined(FEATURE_PAL)
+ _ASSERTE(result == ERROR_SUCCESS);
+
m_currRcw = 0;
}
EventDataDescCreate(&eventData[2], m_etwCcwData, sizeof(EventCCWEntry) * m_currCcw);
ULONG result = EventWrite(Microsoft_Windows_DotNETRuntimeHandle, &GCBulkRootCCW, _countof(eventData), eventData);
- _ASSERTE(result == ERROR_SUCCESS);
#else
-// UNIXTODO: "Eventing Not Implemented"
+ ULONG result = FireEtXplatGCBulkRootCCW(m_currCcw, instance, sizeof(EventCCWEntry) * m_currCcw, m_etwCcwData);
#endif //!defined(FEATURE_PAL)
+ _ASSERTE(result == ERROR_SUCCESS);
m_currCcw = 0;
}
EventDataDescCreate(&eventData[3], m_buffer, m_used);
ULONG result = EventWrite(Microsoft_Windows_DotNETRuntimeHandle, &GCBulkRootStaticVar, _countof(eventData), eventData);
- _ASSERTE(result == ERROR_SUCCESS);
#else
-// UNIXTODO: "Eventing Not Implemented"
+ ULONG result = FireEtXplatGCBulkRootStaticVar(m_count, appDomain, instance, m_used, m_buffer);
#endif //!defined(FEATURE_PAL)
+ _ASSERTE(result == ERROR_SUCCESS);
+
m_used = 0;
m_count = 0;
}
//
//
-#if !defined(FEATURE_PAL)
void BulkTypeEventLogger::FireBulkTypeEvent()
{
LIMITED_METHOD_CONTRACT;
// No types were batched up, so nothing to send
return;
}
+
+ UINT16 nClrInstanceID = GetClrInstanceId();
+#if !defined(FEATURE_PAL)
// Normally, we'd use the MC-generated FireEtwBulkType for all this gunk, but
// it's insufficient as the bulk type event is too complex (arrays of structs of
// varying size). So we directly log the event via EventDataDescCreate and
// before the 64K event size limit, and we already limit our batch size
// (m_nBulkTypeValueCount) to stay within the 128 descriptor limit.
EVENT_DATA_DESCRIPTOR EventData[128];
- UINT16 nClrInstanceID = GetClrInstanceId();
UINT iDesc = 0;
}
Win32EventWrite(Microsoft_Windows_DotNETRuntimeHandle, &BulkType, iDesc, EventData);
+
+#else // FEATURE_PAL
+
+ UINT iSize = 0;
+
+ for (int iTypeData = 0; iTypeData < m_nBulkTypeValueCount; iTypeData++)
+ {
+ BulkTypeValue& target = m_rgBulkTypeValues[iTypeData];
+
+ // Do fixed-size data as one bulk copy
+ memcpy(
+ m_BulkTypeEventBuffer + iSize,
+ &(target.fixedSizedData),
+ sizeof(target.fixedSizedData));
+ iSize += sizeof(target.fixedSizedData);
+
+ // Do var-sized data individually per field
+
+ LPCWSTR wszName = target.sName.GetUnicode();
+ if (wszName == NULL)
+ {
+ m_BulkTypeEventBuffer[iSize++] = 0;
+ m_BulkTypeEventBuffer[iSize++] = 0;
+ }
+ else
+ {
+ UINT nameSize = (target.sName.GetCount() + 1) * sizeof(WCHAR);
+ memcpy(m_BulkTypeEventBuffer + iSize, wszName, nameSize);
+ iSize += nameSize;
+ }
+
+ // Type parameter count
+ ULONG params = target.rgTypeParameters.GetCount();
+
+ ULONG *ptrInt = (ULONG*)(m_BulkTypeEventBuffer + iSize);
+ *ptrInt = params;
+ iSize += 4;
+
+ target.cTypeParameters = params;
+
+ // Type parameter array
+ if (target.cTypeParameters > 0)
+ {
+ memcpy(m_BulkTypeEventBuffer + iSize, target.rgTypeParameters.GetElements(), sizeof(ULONGLONG) * target.cTypeParameters);
+ iSize += sizeof(ULONGLONG) * target.cTypeParameters;
+ }
+ }
+ FireEtwBulkType(m_nBulkTypeValueCount, GetClrInstanceId(), iSize, m_BulkTypeEventBuffer);
+
+#endif // FEATURE_PAL
// Reset state
m_nBulkTypeValueCount = 0;
m_nBulkTypeValueByteCount = 0;
}
-#else
-void BulkTypeEventLogger::FireBulkTypeEvent()
-{
-// UNIXTODO: "Eventing Not Implemented"
-}
-#endif //!defined(FEATURE_PAL)
#ifndef FEATURE_REDHAWK
//---------------------------------------------------------------------------------------
--*/
-#if !defined(FEATURE_PAL)
void InitializeEventTracing()
{
CONTRACTL
if (FAILED(hr))
return;
+#if !defined(FEATURE_PAL)
// Register CLR providers with the OS
if (g_pEtwTracer == NULL)
{
if (tempEtwTracer != NULL && tempEtwTracer->Register () == ERROR_SUCCESS)
g_pEtwTracer = tempEtwTracer.Extract ();
}
+#endif
g_nClrInstanceId = GetRuntimeId() & 0x0000FFFF; // This will give us duplicate ClrInstanceId after UINT16_MAX
// providers can do so now
ETW::TypeSystemLog::PostRegistrationInit();
}
+
+#if !defined(FEATURE_PAL)
HRESULT ETW::CEtwTracer::Register()
{
WRAPPER_NO_CONTRACT;
PMCGEN_TRACE_CONTEXT context = (PMCGEN_TRACE_CONTEXT)CallbackContext;
BOOLEAN bIsPublicTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeHandle);
-
+
BOOLEAN bIsPrivateTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimePrivateHandle);
-
+
BOOLEAN bIsRundownTraceHandle = (context->RegistrationHandle==Microsoft_Windows_DotNETRuntimeRundownHandle);
}
}
-#else
-
-void InitializeEventTracing(){}
-
-#endif // !defined(FEATURE_PAL)
#endif // FEATURE_REDHAWK
+#endif // FEATURE_PAL
#ifndef FEATURE_REDHAWK
/****************************************************************************/
VOID ETW::CodeSymbolLog::EmitCodeSymbols(Module* pModule)
{
+#if !defined(FEATURE_PAL) //UNIXTODO: Enable EmitCodeSymbols
CONTRACTL {
NOTHROW;
GC_NOTRIGGER;
// estmate.
static const DWORD maxDataSize = 63000;
- DWORD quot = length / maxDataSize;
-
+ ldiv_t qr = ldiv(length, maxDataSize);
+
// We do not allow pdbs of size greater than 2GB for now,
// so totalChunks should fit in 16 bits.
- if (quot < UINT16_MAX)
+ if (qr.quot < UINT16_MAX)
{
// If there are trailing bits in the last chunk, then increment totalChunks by 1
- DWORD rem = length % maxDataSize;
- UINT16 totalChunks = (UINT16)(quot + ((rem != 0) ? 1 : 0));
+ UINT16 totalChunks = (UINT16)(qr.quot + ((qr.rem != 0) ? 1 : 0));
NewArrayHolder<BYTE> chunk(new BYTE[maxDataSize]);
DWORD offset = 0;
for (UINT16 chunkNum = 0; offset < length; chunkNum++)
}
}
} EX_CATCH{} EX_END_CATCH(SwallowAllExceptions);
+#endif// !defined(FEATURE_PAL)
}
/* Returns the length of an in-memory symbol stream
BOOL FinalizerThread::fRunFinalizersOnUnload = FALSE;
BOOL FinalizerThread::fQuitFinalizer = FALSE;
+
+#if defined(__linux__)
+#define LINUX_HEAP_DUMP_TIME_OUT 10000
+
+extern bool s_forcedGCInProgress;
+ULONGLONG FinalizerThread::LastHeapDumpTime = 0;
+
+Volatile<BOOL> g_TriggerHeapDump = FALSE;
+#endif // __linux__
+
AppDomain * FinalizerThread::UnloadingAppDomain;
CLREvent * FinalizerThread::hEventFinalizer = NULL;
cEventsForWait, // # objects to wait on
&(MHandles[uiEventIndexOffsetForWait]), // array of objects to wait on
FALSE, // bWaitAll == FALSE, so wait for first signal
+#if defined(__linux__)
+ LINUX_HEAP_DUMP_TIME_OUT,
+#else
INFINITE, // timeout
+#endif
FALSE) // alertable
// Adjust the returned array index for the offset we used, so the return
// Spawn thread to perform the profiler attach, then resume our wait
ProfilingAPIAttachDetach::ProcessSignaledAttachEvent();
break;
-#endif // FEATURE_PROFAPI_ATTACH_DETACH
+#endif // FEATURE_PROFAPI_ATTACH_DETACH
+#if defined(__linux__)
+ case (WAIT_TIMEOUT + kLowMemoryNotification):
+ case (WAIT_TIMEOUT + kFinalizer):
+ if (g_TriggerHeapDump)
+ {
+ return;
+ }
+
+ break;
+#endif
default:
//what's wrong?
_ASSERTE (!"Bad return code from WaitForMultipleObjects");
else {
static LONG sLastLowMemoryFromHost = 0;
while (1) {
+#if defined(__linux__)
+ DWORD timeout = LINUX_HEAP_DUMP_TIME_OUT;
+#else
DWORD timeout = INFINITE;
+#endif
if (!CLRMemoryHosted())
{
if (WaitForSingleObject(MHandles[kLowMemoryNotification], 0) == WAIT_OBJECT_0) {
case (WAIT_ABANDONED):
return;
case (WAIT_TIMEOUT):
+#if defined(__linux__)
+ if (g_TriggerHeapDump)
+ {
+ return;
+ }
+#endif
break;
}
}
WaitForFinalizerEvent (hEventFinalizer);
+#if defined(__linux__)
+ if (g_TriggerHeapDump && (CLRGetTickCount64() > (LastHeapDumpTime + LINUX_HEAP_DUMP_TIME_OUT)))
+ {
+ s_forcedGCInProgress = true;
+ GetFinalizerThread()->DisablePreemptiveGC();
+ GCHeap::GetGCHeap()->GarbageCollect(2, FALSE, collection_blocking);
+ GetFinalizerThread()->EnablePreemptiveGC();
+ s_forcedGCInProgress = false;
+
+ LastHeapDumpTime = CLRGetTickCount64();
+ g_TriggerHeapDump = FALSE;
+ }
+#endif
+
if (!bPriorityBoosted)
{
if (GetFinalizerThread()->SetThreadPriority(THREAD_PRIORITY_HIGHEST))