summaryrefslogtreecommitdiff
path: root/src/vm/eventpipeeventsource.cpp
blob: c67441d73f539e4751c51ef00d92157545bcd837 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// 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.

#include "common.h"
#include "eventpipeeventpayload.h"
#include "eventpipeeventsource.h"
#include "eventpipe.h"
#include "eventpipeevent.h"
#include "eventpipemetadatagenerator.h"
#include "eventpipeprovider.h"
#include "eventpipesession.h"
#include "eventpipesessionprovider.h"

#ifdef FEATURE_PERFTRACING

const WCHAR* EventPipeEventSource::s_pProviderName = W("Microsoft-DotNETCore-EventPipe");
const WCHAR* EventPipeEventSource::s_pProcessInfoEventName = W("ProcessInfo");

EventPipeEventSource::EventPipeEventSource()
{
    CONTRACTL
    {
        THROWS;
        GC_TRIGGERS;
        MODE_ANY;
    }
    CONTRACTL_END;

    m_pProvider = EventPipe::CreateProvider(SL(s_pProviderName), NULL, NULL);

    // Generate metadata.
    const unsigned int numParams = 1;
    EventPipeParameterDesc params[numParams];
    params[0].Type = EventPipeParameterType::String;
    params[0].Name = W("CommandLine");

    size_t metadataLength = 0;
    BYTE *pMetadata = EventPipeMetadataGenerator::GenerateEventMetadata(
        1,      /* eventID */
        s_pProcessInfoEventName,
        0,      /* keywords */
        0,      /* version */
        EventPipeEventLevel::LogAlways,
        params,
        numParams,
        metadataLength);

    // Add the event.
    m_pProcessInfoEvent = m_pProvider->AddEvent(
        1,      /* eventID */
        0,      /* keywords */
        0,      /* eventVersion */
        EventPipeEventLevel::LogAlways,
        false,  /* needStack */
        pMetadata,
        (unsigned int)metadataLength);

    // Delete the metadata after the event is created.
    // The metadata blob will be copied into EventPipe-owned memory.
    delete [] pMetadata;
}

EventPipeEventSource::~EventPipeEventSource()
{
    CONTRACTL
    {
        NOTHROW;
        GC_TRIGGERS;
        MODE_ANY;
    }
    CONTRACTL_END;

    // Delete the provider and associated events.
    // This is called in the shutdown path which can't throw.
    // Catch exceptions and ignore failures.
    EX_TRY
    {
        EventPipe::DeleteProvider(m_pProvider);
    }
    EX_CATCH { }
    EX_END_CATCH(SwallowAllExceptions);
}

void EventPipeEventSource::Enable(EventPipeSession *pSession)
{
    CONTRACTL
    {
        THROWS;
        GC_TRIGGERS;
        MODE_ANY;
        PRECONDITION(pSession != NULL);
    }
    CONTRACTL_END;

    if (pSession == nullptr)
        return;

    pSession->AddSessionProvider(new EventPipeSessionProvider(
        s_pProviderName,
        static_cast<UINT64>(-1),
        EventPipeEventLevel::LogAlways,
        NULL));
}

void EventPipeEventSource::SendProcessInfo(LPCWSTR pCommandLine)
{
    CONTRACTL
    {
        NOTHROW;
        GC_NOTRIGGER;
        MODE_ANY;
    }
    CONTRACTL_END;

    EventData data[1];
    data[0].Ptr = (UINT64) pCommandLine;
    data[0].Size = (unsigned int)(wcslen(pCommandLine) + 1) * 2;
    data[0].Reserved = 0;

    EventPipe::WriteEvent(*m_pProcessInfoEvent, data, 1);
}

#endif // FEATURE_PERFTRACING