-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[EventPipe] Add dotnet_ipc_created mapping #123779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,6 +10,15 @@ | |||||||||||||||
| #include "ep.h" | ||||||||||||||||
| #include "ds-rt.h" | ||||||||||||||||
|
|
||||||||||||||||
| #if HAVE_SYS_MMAN_H && HAVE_MEMFD_CREATE && HAVE_UNISTD_H | ||||||||||||||||
| #include <sys/mman.h> | ||||||||||||||||
| #include <sys/syscall.h> | ||||||||||||||||
| #include <unistd.h> | ||||||||||||||||
| #ifndef MFD_CLOEXEC | ||||||||||||||||
| #define MFD_CLOEXEC 0x0001U | ||||||||||||||||
| #endif | ||||||||||||||||
| #endif | ||||||||||||||||
|
|
||||||||||||||||
| /* | ||||||||||||||||
| * Globals and volatile access functions. | ||||||||||||||||
| */ | ||||||||||||||||
|
|
@@ -332,7 +341,20 @@ ds_ipc_stream_factory_configure (ds_ipc_error_callback_func callback) | |||||||||||||||
| default_port_builder.suspend_mode = port_suspend > 0 ? DS_PORT_SUSPEND_MODE_SUSPEND : DS_PORT_SUSPEND_MODE_NOSUSPEND; | ||||||||||||||||
| default_port_builder.type = DS_PORT_TYPE_LISTEN; | ||||||||||||||||
|
|
||||||||||||||||
| result &= ipc_stream_factory_build_and_add_port (&default_port_builder, callback, true); | ||||||||||||||||
| bool default_listen_port_ready = ipc_stream_factory_build_and_add_port (&default_port_builder, callback, true); | ||||||||||||||||
| #if HAVE_SYS_MMAN_H && HAVE_MEMFD_CREATE && HAVE_UNISTD_H | ||||||||||||||||
| // Create a mapping to signal that the diagnostic server IPC is available. | ||||||||||||||||
| // External tools can use this to detect when the runtime is ready to accept diagnostic commands. | ||||||||||||||||
| // The mapping's lifetime is tied to the process, so tools that start after the .NET process can still detect it. | ||||||||||||||||
| if (default_listen_port_ready) { | ||||||||||||||||
| int fd = (int)syscall (__NR_memfd_create, "dotnet_ipc_created", (unsigned int)MFD_CLOEXEC); | ||||||||||||||||
| if (fd >= 0) { | ||||||||||||||||
| mmap (NULL, 1, PROT_EXEC | PROT_READ, MAP_PRIVATE, fd, 0); | ||||||||||||||||
|
||||||||||||||||
| mmap (NULL, 1, PROT_EXEC | PROT_READ, MAP_PRIVATE, fd, 0); | |
| void *map = mmap (NULL, 1, PROT_EXEC | PROT_READ, MAP_PRIVATE, fd, 0); | |
| if (map == MAP_FAILED) { | |
| // Mapping failed; external tools will not see the readiness signal. | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we fail to create the mapping for some reason, should we even try again and if so, how many times?
Copilot
AI
Jan 29, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PROT_EXEC flag allows pages to be executed, which is a security concern. Since this mapping is only intended as a signal mechanism (the mapped memory is never accessed), PROT_EXEC is unnecessary and violates the principle of least privilege. The mapping should use minimal permissions required for its purpose. Consider using PROT_READ only, or even PROT_NONE if the mere existence of the mapping is sufficient for detection by external tools.
| mmap (NULL, 1, PROT_EXEC | PROT_READ, MAP_PRIVATE, fd, 0); | |
| mmap (NULL, 1, PROT_NONE, MAP_PRIVATE, fd, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried just using PROT_READ (also suggested by Copilot CLI), but when running the userevents tests, it was insufficient for record-trace to discover the mapping.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
record-trace skips non executable mmaps.
https://github.com/microsoft/one-collect/blob/ebdb5acfbf5b767d0d648a74bc302e0807e50000/one_collect/src/helpers/dotnet/os/linux.rs#L1291-L1294
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be at least just PROT_READ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
record-trace skips non executable mmaps.
Can it be changed? That code will need to be modified to check for this mapping instead anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Asked in the record-trace PR microsoft/one-collect#229 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we have this memory map indicating that we have a diagnostic server up and running, I believe that is a much better indicator than the doublemapper they used in the past, so maybe they should steer away from that and only use this instead to find dotnet processes that support tracing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why only create this when using the default listener port? On some platforms we don't build with the default listener, but you can still setup diagnostic ports using the DOTNET_DiagnosticPorts env variable, so believe this should be done when we have any diagnostic port setup and started, not just the default.