summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/debug/debug-pal/CMakeLists.txt4
-rw-r--r--src/debug/debug-pal/unix/diagnosticsipc.cpp51
-rw-r--r--src/debug/debug-pal/win/diagnosticsipc.cpp4
-rw-r--r--src/debug/inc/diagnosticsipc.h19
-rw-r--r--src/inc/loglf.h2
-rw-r--r--src/vm/diagnosticserver.cpp38
-rw-r--r--src/vm/diagnosticserver.h8
-rw-r--r--src/vm/fastserializer.cpp1
-rw-r--r--src/vm/fastserializer.h3
9 files changed, 99 insertions, 31 deletions
diff --git a/src/debug/debug-pal/CMakeLists.txt b/src/debug/debug-pal/CMakeLists.txt
index c1b5b443a9..ac0f97e468 100644
--- a/src/debug/debug-pal/CMakeLists.txt
+++ b/src/debug/debug-pal/CMakeLists.txt
@@ -5,12 +5,10 @@ include_directories(../../pal/inc)
add_definitions(-DPAL_STDCPP_COMPAT=1)
if(WIN32)
- #use static crt
- add_definitions(-MT)
add_definitions(-DWIN32_LEAN_AND_MEAN)
include_directories(../../inc) #needed for warning control
- set(TWO_WAY_PIPE_SOURCES
+ set(TWO_WAY_PIPE_SOURCES
win/diagnosticsipc.cpp
win/twowaypipe.cpp
win/processdescriptor.cpp
diff --git a/src/debug/debug-pal/unix/diagnosticsipc.cpp b/src/debug/debug-pal/unix/diagnosticsipc.cpp
index 182dff01be..d9e0e94c9f 100644
--- a/src/debug/debug-pal/unix/diagnosticsipc.cpp
+++ b/src/debug/debug-pal/unix/diagnosticsipc.cpp
@@ -7,7 +7,6 @@
#include <new>
#include <unistd.h>
#include <fcntl.h>
-#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "diagnosticsipc.h"
@@ -15,7 +14,8 @@
IpcStream::DiagnosticsIpc::DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress) :
_serverSocket(serverSocket),
- _pServerAddress(new (std::nothrow) sockaddr_un)
+ _pServerAddress(new (std::nothrow) sockaddr_un),
+ _isUnlinked(false)
{
_ASSERTE(_pServerAddress != nullptr);
_ASSERTE(_serverSocket != -1);
@@ -33,8 +33,7 @@ IpcStream::DiagnosticsIpc::~DiagnosticsIpc()
const int fSuccessClose = ::close(_serverSocket);
_ASSERTE(fSuccessClose != -1); // TODO: Add error handling?
- const int fSuccessUnlink = ::unlink(_pServerAddress->sun_path);
- _ASSERTE(fSuccessUnlink != -1); // TODO: Add error handling?
+ Unlink();
delete _pServerAddress;
}
@@ -68,6 +67,26 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p
if (callback != nullptr)
callback(strerror(errno), errno);
_ASSERTE(fSuccessBind != -1);
+
+ const int fSuccessClose = ::close(serverSocket);
+ _ASSERTE(fSuccessClose != -1);
+
+ return nullptr;
+ }
+
+ const int fSuccessfulListen = ::listen(serverSocket, /* backlog */ 255);
+ if (fSuccessfulListen == -1)
+ {
+ if (callback != nullptr)
+ callback(strerror(errno), errno);
+ _ASSERTE(fSuccessfulListen != -1);
+
+ const int fSuccessUnlink = ::unlink(serverAddress.sun_path);
+ _ASSERTE(fSuccessUnlink != -1);
+
+ const int fSuccessClose = ::close(serverSocket);
+ _ASSERTE(fSuccessClose != -1);
+
return nullptr;
}
@@ -76,8 +95,6 @@ IpcStream::DiagnosticsIpc *IpcStream::DiagnosticsIpc::Create(const char *const p
IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const
{
- if (::listen(_serverSocket, /* backlog */ 255) == -1)
- return nullptr;
sockaddr_un from;
socklen_t fromlen = sizeof(from);
const int clientSocket = ::accept(_serverSocket, (sockaddr *)&from, &fromlen);
@@ -94,6 +111,28 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const
return pIpcStream;
}
+//! This helps remove the socket from the filesystem when the runtime exits.
+//! From: http://man7.org/linux/man-pages/man7/unix.7.html#NOTES
+//! Binding to a socket with a filename creates a socket in the
+//! filesystem that must be deleted by the caller when it is no longer
+//! needed (using unlink(2)). The usual UNIX close-behind semantics
+//! apply; the socket can be unlinked at any time and will be finally
+//! removed from the filesystem when the last reference to it is closed.
+void IpcStream::DiagnosticsIpc::Unlink(ErrorCallback callback)
+{
+ if (_isUnlinked)
+ return;
+ _isUnlinked = true;
+
+ const int fSuccessUnlink = ::unlink(_pServerAddress->sun_path);
+ if (fSuccessUnlink == -1)
+ {
+ if (callback != nullptr)
+ callback(strerror(errno), errno);
+ _ASSERTE(fSuccessUnlink == 0);
+ }
+}
+
IpcStream::~IpcStream()
{
if (_clientSocket != -1)
diff --git a/src/debug/debug-pal/win/diagnosticsipc.cpp b/src/debug/debug-pal/win/diagnosticsipc.cpp
index 7d9f84e7e5..46f212836b 100644
--- a/src/debug/debug-pal/win/diagnosticsipc.cpp
+++ b/src/debug/debug-pal/win/diagnosticsipc.cpp
@@ -77,6 +77,10 @@ IpcStream *IpcStream::DiagnosticsIpc::Accept(ErrorCallback callback) const
return pIpcStream;
}
+void IpcStream::DiagnosticsIpc::Unlink(ErrorCallback callback)
+{
+}
+
IpcStream::~IpcStream()
{
if (_hPipe != INVALID_HANDLE_VALUE)
diff --git a/src/debug/inc/diagnosticsipc.h b/src/debug/inc/diagnosticsipc.h
index 81789f0803..54277e1af9 100644
--- a/src/debug/inc/diagnosticsipc.h
+++ b/src/debug/inc/diagnosticsipc.h
@@ -26,20 +26,31 @@ public:
class DiagnosticsIpc final
{
public:
- static DiagnosticsIpc *Create(const char *const pIpcName, ErrorCallback callback = nullptr);
~DiagnosticsIpc();
+
+ //! Creates an IPC object
+ static DiagnosticsIpc *Create(const char *const pIpcName, ErrorCallback callback = nullptr);
+
+ //! Enables the underlaying IPC implementation to accept connection.
IpcStream *Accept(ErrorCallback callback = nullptr) const;
+ //! Used to unlink the socket so it can be removed from the filesystem
+ //! when the last reference to it is closed.
+ void Unlink(ErrorCallback callback = nullptr);
+
private:
#ifdef FEATURE_PAL
- DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress);
- const int _serverSocket = -1;
+ const int _serverSocket;
sockaddr_un *const _pServerAddress;
+ bool _isUnlinked = false;
+
+ DiagnosticsIpc(const int serverSocket, sockaddr_un *const pServerAddress);
#else
static const uint32_t MaxNamedPipeNameLength = 256;
- DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength]);
char _pNamedPipeName[MaxNamedPipeNameLength]; // https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-createnamedpipea
+
+ DiagnosticsIpc(const char(&namedPipeName)[MaxNamedPipeNameLength]);
#endif /* FEATURE_PAL */
DiagnosticsIpc() = delete;
diff --git a/src/inc/loglf.h b/src/inc/loglf.h
index e7fbd519d9..76a9897b53 100644
--- a/src/inc/loglf.h
+++ b/src/inc/loglf.h
@@ -16,7 +16,7 @@ DEFINE_LOG_FACILITY(LF_GCALLOC ,0x00000100)
DEFINE_LOG_FACILITY(LF_CORDB ,0x00000200)
DEFINE_LOG_FACILITY(LF_CLASSLOADER ,0x00000400)
DEFINE_LOG_FACILITY(LF_CORPROF ,0x00000800)
-DEFINE_LOG_FACILITY(LF_REMOTING ,0x00001000)
+DEFINE_LOG_FACILITY(LF_DIAGNOSTICS_PORT ,0x00001000)
DEFINE_LOG_FACILITY(LF_DBGALLOC ,0x00002000)
DEFINE_LOG_FACILITY(LF_EH ,0x00004000)
DEFINE_LOG_FACILITY(LF_ENC ,0x00008000)
diff --git a/src/vm/diagnosticserver.cpp b/src/vm/diagnosticserver.cpp
index c0e11d100f..3a700383ac 100644
--- a/src/vm/diagnosticserver.cpp
+++ b/src/vm/diagnosticserver.cpp
@@ -4,7 +4,6 @@
#include "common.h"
#include "diagnosticserver.h"
-#include "diagnosticsipc.h"
#include "eventpipeprotocolhelper.h"
#ifdef FEATURE_PAL
@@ -13,6 +12,8 @@
#ifdef FEATURE_PERFTRACING
+IpcStream::DiagnosticsIpc *DiagnosticServer::s_pIpc = nullptr;
+
static DWORD WINAPI DiagnosticsServerThread(LPVOID lpThreadParameter)
{
CONTRACTL
@@ -28,17 +29,13 @@ static DWORD WINAPI DiagnosticsServerThread(LPVOID lpThreadParameter)
auto pIpc = reinterpret_cast<IpcStream::DiagnosticsIpc *>(lpThreadParameter);
if (pIpc == nullptr)
{
- STRESS_LOG0(LF_STARTUP, LL_ERROR,"Diagnostics IPC listener was undefined\n");
+ STRESS_LOG0(LF_DIAGNOSTICS_PORT, LL_ERROR, "Diagnostics IPC listener was undefined\n");
return 1;
}
-#ifdef _DEBUG
ErrorCallback LoggingCallback = [](const char *szMessage, uint32_t code) {
- LOG((LF_REMOTING, LL_WARNING, "warning (%d): %s.\n", code, szMessage));
+ STRESS_LOG2(LF_DIAGNOSTICS_PORT, LL_WARNING, "warning (%d): %s.\n", code, szMessage);
};
-#else
- ErrorCallback LoggingCallback = nullptr;
-#endif
while (true)
{
@@ -69,7 +66,7 @@ static DWORD WINAPI DiagnosticsServerThread(LPVOID lpThreadParameter)
break;
default:
- LOG((LF_REMOTING, LL_WARNING, "Received unknow request type (%d)\n", header.RequestType));
+ LOG((LF_DIAGNOSTICS_PORT, LL_WARNING, "Received unknow request type (%d)\n", header.RequestType));
break;
}
}
@@ -93,23 +90,25 @@ bool DiagnosticServer::Initialize()
{
auto ErrorCallback = [](const char *szMessage, uint32_t code) {
STRESS_LOG2(
- LF_STARTUP, // facility
+ LF_DIAGNOSTICS_PORT, // facility
LL_ERROR, // level
"Failed to create diagnostic IPC: error (%d): %s.\n", // msg
code, // data1
szMessage); // data2
};
- IpcStream::DiagnosticsIpc *pIpc = IpcStream::DiagnosticsIpc::Create(
+
+ // TODO: Should we handle/assert that (s_pIpc == nullptr)?
+ s_pIpc = IpcStream::DiagnosticsIpc::Create(
"dotnetcore-diagnostic", ErrorCallback);
- if (pIpc != nullptr)
+ if (s_pIpc != nullptr)
{
DWORD dwThreadId = 0;
HANDLE hThread = ::CreateThread( // TODO: Is it correct to have this "lower" level call here?
nullptr, // no security attribute
0, // default stack size
DiagnosticsServerThread, // thread proc
- (LPVOID)pIpc, // thread parameter
+ (LPVOID)s_pIpc, // thread parameter
0, // not suspended
&dwThreadId); // returns thread ID
@@ -117,7 +116,7 @@ bool DiagnosticServer::Initialize()
{
// Failed to create IPC thread.
STRESS_LOG1(
- LF_STARTUP, // facility
+ LF_DIAGNOSTICS_PORT, // facility
LL_ERROR, // level
"Failed to create diagnostic server thread (%d).\n", // msg
::GetLastError()); // data1
@@ -155,7 +154,18 @@ bool DiagnosticServer::Shutdown()
EX_TRY
{
- // FIXME: Stop IPC server thread?
+ if (s_pIpc != nullptr)
+ {
+ auto ErrorCallback = [](const char *szMessage, uint32_t code) {
+ STRESS_LOG2(
+ LF_DIAGNOSTICS_PORT, // facility
+ LL_ERROR, // level
+ "Failed to unlink diagnostic IPC: error (%d): %s.\n", // msg
+ code, // data1
+ szMessage); // data2
+ };
+ s_pIpc->Unlink(ErrorCallback);
+ }
fSuccess = true;
}
EX_CATCH
diff --git a/src/vm/diagnosticserver.h b/src/vm/diagnosticserver.h
index 95399a2ef8..51f32ae09f 100644
--- a/src/vm/diagnosticserver.h
+++ b/src/vm/diagnosticserver.h
@@ -5,10 +5,11 @@
#ifndef __DIAGNOSTIC_SERVER_H__
#define __DIAGNOSTIC_SERVER_H__
-#include <stdint.h>
-
#ifdef FEATURE_PERFTRACING // This macro should change to something more generic than performance.
+#include <stdint.h>
+#include "diagnosticsipc.h"
+
//! TODO: Temp class.
enum class DiagnosticMessageType : uint32_t
{
@@ -51,6 +52,9 @@ public:
//! Shutdown the event pipe.
static bool Shutdown();
+
+private:
+ static IpcStream::DiagnosticsIpc *s_pIpc;
};
#endif // FEATURE_PERFTRACING
diff --git a/src/vm/fastserializer.cpp b/src/vm/fastserializer.cpp
index 89dbe50728..e02ec93010 100644
--- a/src/vm/fastserializer.cpp
+++ b/src/vm/fastserializer.cpp
@@ -4,6 +4,7 @@
#include "common.h"
#include "fastserializer.h"
+#include "diagnosticsipc.h"
#ifdef FEATURE_PERFTRACING
diff --git a/src/vm/fastserializer.h b/src/vm/fastserializer.h
index 3b4de65bf5..98208c0eb1 100644
--- a/src/vm/fastserializer.h
+++ b/src/vm/fastserializer.h
@@ -11,7 +11,8 @@
#include "fastserializableobject.h"
#include "fstream.h"
-#include "diagnosticsipc.h"
+
+class IpcStream;
// the enumeration has a specific set of values to keep it compatible with consumer library
// it's sibling is defined in https://github.com/Microsoft/perfview/blob/10d1f92b242c98073b3817ac5ee6d98cd595d39b/src/FastSerialization/FastSerialization.cs#L2295