8bbe3b6c4e2855aad10d587ad0d93a90bddab80b
[platform/upstream/dotnet/runtime.git] / src / native / eventpipe / ep-event-source.c
1 #include "ep-rt-config.h"
2
3 #ifdef ENABLE_PERFTRACING
4 #if !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES)
5
6 #define EP_IMPL_EVENT_SOURCE_GETTER_SETTER
7 #include "ep.h"
8 #include "ep-event-source.h"
9 #include "ep-event-payload.h"
10 #include "ep-metadata-generator.h"
11 #include "ep-session.h"
12 #include "ep-session-provider.h"
13 #include "ep-rt.h"
14
15 #if defined(HOST_WINDOWS) || defined(HOST_WIN32)
16 const ep_char8_t* _ep_os_info = "Windows";
17 #elif defined(HOST_TVOS)
18 const ep_char8_t* _ep_os_info = "tvOS";
19 #elif defined(HOST_IOS)
20 const ep_char8_t* _ep_os_info = "iOS";
21 #elif defined(HOST_WATCHOS)
22 const ep_char8_t* _ep_os_info = "watchOS";
23 #elif defined(HOST_MACCAT)
24 const ep_char8_t* _ep_os_info = "MacCatalyst";
25 #elif defined(__APPLE__)
26 const ep_char8_t* _ep_os_info = "macOS";
27 #elif defined(HOST_ANDROID)
28 const ep_char8_t* _ep_os_info = "Android";
29 #elif defined(__linux__)
30 const ep_char8_t* _ep_os_info = "Linux";
31 #else
32 const ep_char8_t* _ep_os_info = "Unknown";
33 #endif
34
35 #if defined(TARGET_X86)
36 const ep_char8_t* _ep_arch_info = "x86";
37 #elif defined(TARGET_AMD64)
38 const ep_char8_t* _ep_arch_info = "x64";
39 #elif defined(TARGET_ARMV6)
40 const ep_char8_t* _ep_arch_info = "arm32";
41 #elif defined(TARGET_ARM)
42 const ep_char8_t* _ep_arch_info = "arm32";
43 #elif defined(TARGET_ARM64)
44 const ep_char8_t* _ep_arch_info = "arm64";
45 #elif defined(TARGET_S390X)
46 const ep_char8_t* _ep_arch_info = "s390x";
47 #elif defined(TARGET_LOONGARCH64)
48 const ep_char8_t* _ep_arch_info = "loongarch64";
49 #elif defined(TARGET_POWERPC64)
50 const ep_char8_t* _ep_arch_info = "ppc64le";
51 #else
52 const ep_char8_t* _ep_arch_info = "Unknown";
53 #endif
54
55 EventPipeEventSource _ep_event_source_instance = { 0 };
56
57 /*
58  * Forward declares of all static functions.
59  */
60
61 static
62 void
63 event_source_fini (EventPipeEventSource *event_source);
64
65 /*
66  * EventPipeEventSource.
67  */
68
69 static
70 void
71 event_source_fini (EventPipeEventSource *event_source)
72 {
73         ep_delete_provider (event_source->provider);
74 }
75
76 EventPipeEventSource *
77 ep_event_source_alloc (void)
78 {
79         EventPipeEventSource *instance = ep_rt_object_alloc (EventPipeEventSource);
80         ep_raise_error_if_nok (instance != NULL);
81         ep_raise_error_if_nok (ep_event_source_init (instance) != NULL);
82
83 ep_on_exit:
84         return instance;
85
86 ep_on_error:
87         ep_event_source_free (instance);
88         instance = NULL;
89         ep_exit_error_handler ();
90 }
91
92 EventPipeEventSource *
93 ep_event_source_init (EventPipeEventSource *event_source)
94 {
95         ep_char16_t *command_line_arg_utf16 = NULL;
96         ep_char16_t *os_info_arg_utf16 = NULL;
97         ep_char16_t *arch_info_arg_utf16 = NULL;
98         ep_char16_t *event_name_utf16  = NULL;
99         uint8_t *metadata = NULL;
100
101         EP_ASSERT (event_source != NULL);
102
103         event_source->provider = ep_create_provider (ep_provider_get_default_name_utf8 (), NULL, NULL);
104         ep_raise_error_if_nok (event_source->provider != NULL);
105
106         event_source->provider_name = ep_provider_get_default_name_utf8 ();
107
108         // Generate metadata.
109         EventPipeParameterDesc params [3];
110         uint32_t params_len;
111         params_len = (uint32_t)ARRAY_SIZE (params);
112
113         command_line_arg_utf16 = ep_rt_utf8_to_utf16le_string ("CommandLine", -1);
114         ep_raise_error_if_nok (command_line_arg_utf16 != NULL);
115         ep_parameter_desc_init (&params[0], EP_PARAMETER_TYPE_STRING, command_line_arg_utf16);
116
117         os_info_arg_utf16 = ep_rt_utf8_to_utf16le_string ("OSInformation", -1);
118         ep_raise_error_if_nok (os_info_arg_utf16 != NULL);
119         ep_parameter_desc_init (&params[1], EP_PARAMETER_TYPE_STRING, os_info_arg_utf16);
120
121         arch_info_arg_utf16 = ep_rt_utf8_to_utf16le_string ("ArchInformation", -1);
122         ep_raise_error_if_nok (arch_info_arg_utf16 != NULL);
123         ep_parameter_desc_init (&params[2], EP_PARAMETER_TYPE_STRING, arch_info_arg_utf16);
124
125         event_name_utf16 = ep_rt_utf8_to_utf16le_string ("ProcessInfo", -1);
126         ep_raise_error_if_nok (event_name_utf16 != NULL);
127
128         size_t metadata_len;
129         metadata_len = 0;
130         metadata = ep_metadata_generator_generate_event_metadata (
131                 1,              /* eventID */
132                 event_name_utf16,
133                 0,              /* keywords */
134                 1,              /* version */
135                 EP_EVENT_LEVEL_LOGALWAYS,
136                 0,              /* opcode */
137                 params,
138                 params_len,
139                 &metadata_len);
140
141         ep_raise_error_if_nok (metadata != NULL);
142
143         // Add the event.
144         event_source->process_info_event = ep_provider_add_event (
145                 event_source->provider,
146                 1,              /* eventID */
147                 0,              /* keywords */
148                 0,              /* eventVersion */
149                 EP_EVENT_LEVEL_LOGALWAYS,
150                 false,  /* needStack */
151                 metadata,
152                 (uint32_t)metadata_len);
153
154         ep_raise_error_if_nok (event_source->process_info_event);
155
156 ep_on_exit:
157         // Delete the metadata after the event is created.
158         // The metadata blob will be copied into EventPipe-owned memory.
159         ep_rt_byte_array_free (metadata);
160
161         // Delete the strings after the event is created.
162         // The strings will be copied into EventPipe-owned memory.
163         ep_rt_utf16_string_free (event_name_utf16);
164         ep_rt_utf16_string_free (arch_info_arg_utf16);
165         ep_rt_utf16_string_free (os_info_arg_utf16);
166         ep_rt_utf16_string_free (command_line_arg_utf16);
167
168         return event_source;
169
170 ep_on_error:
171         ep_event_source_free (event_source);
172
173         event_source = NULL;
174         ep_exit_error_handler ();
175 }
176
177 void
178 ep_event_source_fini (EventPipeEventSource *event_source)
179 {
180         ep_return_void_if_nok (event_source);
181         event_source_fini (event_source);
182 }
183
184 void
185 ep_event_source_free (EventPipeEventSource *event_source)
186 {
187         ep_return_void_if_nok (event_source);
188         event_source_fini (event_source);
189         ep_rt_object_free (event_source);
190 }
191
192 bool
193 ep_event_source_enable (
194         EventPipeEventSource *event_source,
195         EventPipeSession *session)
196 {
197         EP_ASSERT (event_source != NULL);
198         EP_ASSERT (session != NULL);
199
200         ep_requires_lock_held ();
201
202         bool result = true;
203         EventPipeSessionProvider *session_provider = ep_session_provider_alloc (event_source->provider_name, (uint64_t)-1, EP_EVENT_LEVEL_LOGALWAYS, NULL);
204         if (session_provider != NULL)
205                 result = ep_session_add_session_provider (session, session_provider);
206         return result;
207 }
208
209 void
210 ep_event_source_send_process_info (
211         EventPipeEventSource * event_source,
212         const ep_char8_t *command_line)
213 {
214         EP_ASSERT (event_source != NULL);
215
216         ep_char16_t *command_line_utf16 = NULL;
217         ep_char16_t *os_info_utf16 = NULL;
218         ep_char16_t *arch_info_utf16 = NULL;
219
220         command_line_utf16 = ep_rt_utf8_to_utf16le_string (command_line, -1);
221         os_info_utf16 = ep_rt_utf8_to_utf16le_string (ep_event_source_get_os_info (), -1);
222         arch_info_utf16 = ep_rt_utf8_to_utf16le_string (ep_event_source_get_arch_info (), -1);
223
224         EventData data [3] = { { 0 } };
225         if (command_line_utf16)
226                 ep_event_data_init (&data[0], (uint64_t)command_line_utf16, (uint32_t)((ep_rt_utf16_string_len (command_line_utf16) + 1) * sizeof (ep_char16_t)), 0);
227         if (os_info_utf16)
228                 ep_event_data_init (&data[1], (uint64_t)os_info_utf16, (uint32_t)((ep_rt_utf16_string_len (os_info_utf16) + 1) * sizeof (ep_char16_t)), 0);
229         if (arch_info_utf16)
230                 ep_event_data_init (&data[2], (uint64_t)arch_info_utf16, (uint32_t)((ep_rt_utf16_string_len (arch_info_utf16) + 1) * sizeof (ep_char16_t)), 0);
231
232         ep_write_event_2 (event_source->process_info_event, data, (uint32_t)ARRAY_SIZE (data), NULL, NULL);
233
234         ep_rt_utf16_string_free (arch_info_utf16);
235         ep_rt_utf16_string_free (os_info_utf16);
236         ep_rt_utf16_string_free (command_line_utf16);
237 }
238
239 #endif /* !defined(EP_INCLUDE_SOURCE_FILES) || defined(EP_FORCE_INCLUDE_SOURCE_FILES) */
240 #endif /* ENABLE_PERFTRACING */
241
242 #if !defined(ENABLE_PERFTRACING) || (defined(EP_INCLUDE_SOURCE_FILES) && !defined(EP_FORCE_INCLUDE_SOURCE_FILES))
243 extern const char quiet_linker_empty_file_warning_eventpipe_event_source;
244 const char quiet_linker_empty_file_warning_eventpipe_event_source = 0;
245 #endif