in src/LttngHelpers.c [1244:1467]
int lttngh_EventProbe(
struct lttng_ust_tracepoint *pTracepoint,
struct lttngh_DataDesc *pDataDesc,
unsigned cDataDesc,
void *pCallerIp)
{
int err = 0;
struct lttng_ust_tracepoint_probe *pTpProbe;
unsigned char transcodeScratchOnStack[256] __attribute__((aligned(2)));
struct lttngh_EventProbeContext context = {
.maxAlign = 0, // 0 means we haven't computed event size yet.
.cbData = 0,
.pbTranscodeScratch = transcodeScratchOnStack,
.cbTranscodeScratch = sizeof(transcodeScratchOnStack) };
if (pCallerIp == NULL)
{
pCallerIp = lttngh_IP_PARAM;
}
lttng_ust_urcu_read_lock();
pTpProbe = lttng_ust_rcu_dereference(pTracepoint->probes);
if (caa_likely(pTpProbe))
{
do
{
lttngh_ust_event_common* const pEvent = (lttngh_ust_event_common* const)pTpProbe->data;
#if lttngh_UST_VER >= 213
if (caa_likely(pEvent->type == LTTNG_UST_EVENT_TYPE_RECORDER))
{
struct lttng_ust_event_recorder* pEventRecorder = (struct lttng_ust_event_recorder*)pEvent->child;
struct lttng_ust_channel_common* pChannelCommon = pEventRecorder->chan->parent;
if (
#ifdef TP_SESSION_CHECK // Are we building statedump?
session != pChannelCommon->session ||
#endif // TP_SESSION_CHECK
caa_unlikely(!CMM_ACCESS_ONCE(pChannelCommon->session->active)) ||
caa_unlikely(!CMM_ACCESS_ONCE(pChannelCommon->enabled)))
{
continue;
}
if (caa_unlikely(!CMM_ACCESS_ONCE(pEvent->enabled)))
{
continue;
}
if (caa_unlikely(CMM_ACCESS_ONCE(pEvent->eval_filter)) &&
!caa_unlikely(EventProbeFilter(pEvent, pCallerIp, pDataDesc, cDataDesc)))
{
continue;
}
// Compute event size the first time through.
if (caa_likely(context.maxAlign == 0))
{
err = EventProbeComputeSizes(&context, pDataDesc, cDataDesc);
if (err != 0)
{
goto Done;
}
}
struct lttng_ust_channel_buffer* pChannel = pEventRecorder->chan;
struct lttng_ust_ring_buffer_ctx bufferContext;
lttng_ust_ring_buffer_ctx_init(&bufferContext, pEventRecorder, context.cbData, context.maxAlign, pCallerIp);
int const reserveResult = pChannel->ops->event_reserve(&bufferContext);
if (caa_unlikely(reserveResult < 0))
{
err = reserveResult;
}
else
{
unsigned i;
for (i = 0; i != cDataDesc; i += 1)
{
uint16_t cbUtf8Written;
switch (pDataDesc[i].Type)
{
case lttngh_DataType_String8:
pChannel->ops->event_strcpy(&bufferContext, pDataDesc[i].Data, pDataDesc[i].Size);
break;
case lttngh_DataType_StringUtf16Transcoded:
case lttngh_DataType_StringUtf32Transcoded:
cbUtf8Written = EventProbeTranscodeString(&context, &pDataDesc[i]);
pChannel->ops->event_write(&bufferContext, context.pbTranscodeScratch, cbUtf8Written + 1u, pDataDesc[i].Alignment);
break;
case lttngh_DataType_SequenceUtf16Transcoded:
case lttngh_DataType_SequenceUtf32Transcoded:
cbUtf8Written = EventProbeTranscodeSequence(&context, &pDataDesc[i]);
pChannel->ops->event_write(&bufferContext, context.pbTranscodeScratch, sizeof(uint16_t) + cbUtf8Written, pDataDesc[i].Alignment);
break;
default:
pChannel->ops->event_write(&bufferContext, pDataDesc[i].Data, pDataDesc[i].Size, pDataDesc[i].Alignment);
break;
}
}
pChannel->ops->event_commit(&bufferContext);
}
}
else if (caa_likely(CMM_ACCESS_ONCE(pEvent->enabled)))
{
if (caa_likely(pEvent->type == LTTNG_UST_EVENT_TYPE_NOTIFIER) ||
caa_unlikely(CMM_ACCESS_ONCE(pEvent->eval_filter)))
{
(void)EventProbeFilter(pEvent, pCallerIp, pDataDesc, cDataDesc);
}
}
#else // lttngh_UST_VER
struct lttng_channel const *const pChannel = pEvent->chan;
if (caa_likely(CMM_ACCESS_ONCE(pChannel->session->active)) &&
caa_likely(CMM_ACCESS_ONCE(pChannel->enabled)) &&
caa_likely(CMM_ACCESS_ONCE(pEvent->enabled)) &&
#ifdef TP_SESSION_CHECK // Are we building statedump?
session == pChannel->session &&
#endif // TP_SESSION_CHECK
(caa_likely(cds_list_empty(&pEvent->bytecode_runtime_head)) ||
caa_unlikely(EventProbeFilter(pEvent, pDataDesc, cDataDesc))))
{
// Compute event size the first time through.
if (caa_likely(context.maxAlign == 0))
{
err = EventProbeComputeSizes(&context, pDataDesc, cDataDesc);
if (err != 0)
{
goto Done;
}
}
#if lttngh_UST_VER >= 208
struct lttng_stack_ctx stackContext;
memset(&stackContext, 0, sizeof(stackContext));
stackContext.event = pEvent;
stackContext.chan_ctx = lttng_ust_rcu_dereference(pChannel->ctx);
stackContext.event_ctx = lttng_ust_rcu_dereference(pEvent->ctx);
#endif // lttngh_UST_VER >= 208
struct lttng_ust_lib_ring_buffer_ctx bufferContext;
lib_ring_buffer_ctx_init(&bufferContext, pChannel->chan, pEvent,
context.cbData, (int)context.maxAlign, -1, pChannel->handle
#if lttngh_UST_VER >= 208
,
&stackContext
#endif // lttngh_UST_VER >= 208
);
bufferContext.ip = pCallerIp;
int const reserveResult = pChannel->ops->event_reserve(&bufferContext, pEvent->id);
if (caa_unlikely(reserveResult < 0))
{
err = reserveResult;
}
else
{
unsigned i;
for (i = 0; i != cDataDesc; i += 1)
{
uint16_t cbUtf8Written;
#if lttngh_UST_RING_BUFFER_NATURAL_ALIGN
lib_ring_buffer_align_ctx(&bufferContext, pDataDesc[i].Alignment);
#endif // lttngh_UST_RING_BUFFER_NATURAL_ALIGN
switch (pDataDesc[i].Type)
{
case lttngh_DataType_String8:
if (pChannel->ops->u.has_strcpy)
{
pChannel->ops->event_strcpy(&bufferContext, (char const*)pDataDesc[i].Data, pDataDesc[i].Size);
}
else
{
pChannel->ops->event_write(&bufferContext, pDataDesc[i].Data, pDataDesc[i].Size);
}
break;
case lttngh_DataType_StringUtf16Transcoded:
case lttngh_DataType_StringUtf32Transcoded:
cbUtf8Written = EventProbeTranscodeString(&context, &pDataDesc[i]);
pChannel->ops->event_write(&bufferContext, context.pbTranscodeScratch, cbUtf8Written + 1u);
break;
case lttngh_DataType_SequenceUtf16Transcoded:
case lttngh_DataType_SequenceUtf32Transcoded:
cbUtf8Written = EventProbeTranscodeSequence(&context, &pDataDesc[i]);
pChannel->ops->event_write(&bufferContext, context.pbTranscodeScratch, sizeof(uint16_t) + cbUtf8Written);
break;
default:
pChannel->ops->event_write(&bufferContext, pDataDesc[i].Data, pDataDesc[i].Size);
break;
}
}
pChannel->ops->event_commit(&bufferContext);
}
}
#endif // lttngh_UST_VER
} while ((++pTpProbe)->data);
}
Done:
lttng_ust_urcu_read_unlock();
if (caa_unlikely(context.pbTranscodeScratch != transcodeScratchOnStack))
{
free(context.pbTranscodeScratch);
}
return err;
}