summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/util/log.cpp84
-rw-r--r--src/mongo/util/log.h1
-rw-r--r--src/mongo/util/processinfo.cpp15
3 files changed, 65 insertions, 35 deletions
diff --git a/src/mongo/util/log.cpp b/src/mongo/util/log.cpp
index 75720dbcf7f..b3c130bf264 100644
--- a/src/mongo/util/log.cpp
+++ b/src/mongo/util/log.cpp
@@ -54,6 +54,11 @@ using namespace std;
namespace mongo {
+namespace {
+const char kUnknownMsg[] = "Unknown error";
+const int kBuflen = 256; // strerror strings in non-English locales can be large.
+}
+
static logger::ExtraLogContextFn _appendExtraLogContext;
Status logger::registerExtraLogContextFn(logger::ExtraLogContextFn contextFn) {
@@ -81,50 +86,69 @@ bool rotateLogs(bool renameFiles) {
return result.empty();
}
-string errnoWithDescription(int x) {
+string errnoWithDescription(int errNumber) {
#if defined(_WIN32)
- if (x < 0)
- x = GetLastError();
+ if (errNumber < 0)
+ errNumber = GetLastError();
#else
- if (x < 0)
- x = errno;
+ if (errNumber < 0)
+ errNumber = errno;
#endif
- stringstream s;
- s << "errno:" << x << ' ';
-#if defined(_WIN32)
- LPWSTR errorText = NULL;
+ char buf[kBuflen];
+ char* msg{nullptr};
+
+#if defined(__GNUC__) && defined(_GNU_SOURCE)
+ msg = strerror_r(errNumber, buf, kBuflen);
+#elif defined(_WIN32)
+
+ LPWSTR errorText = nullptr;
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- x,
+ nullptr,
+ errNumber,
0,
reinterpret_cast<LPWSTR>(&errorText), // output
0, // minimum size for output buffer
- NULL);
+ nullptr);
+
if (errorText) {
- string x = toUtf8String(errorText);
- for (string::iterator i = x.begin(); i != x.end(); i++) {
- if (*i == '\n' || *i == '\r')
- break;
- s << *i;
+ string utf8ErrorText = toUtf8String(errorText);
+ auto size = utf8ErrorText.find_first_of("\r\n");
+ if (size == string::npos) { // not found
+ size = utf8ErrorText.length();
+ }
+
+ if (size > kBuflen) {
+ size = kBuflen;
}
+
+ memcpy(buf, utf8ErrorText.c_str(), size);
+ msg = buf;
LocalFree(errorText);
- } else
- s << strerror(x);
-/*
-DWORD n = FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, x,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &lpMsgBuf, 0, NULL);
-*/
+ } else if (strerror_s(buf, kBuflen, errNumber) != 0) {
+ msg = buf;
+ }
+#else /* XSI strerror_r */
+ if (strerror_r(errNumber, buf, kBuflen) == 0) {
+ msg = buf;
+ }
+#endif
+
+ if (!msg) {
+ return {kUnknownMsg};
+ }
+
+ return {msg};
+}
+
+std::pair<int, std::string> errnoAndDescription() {
+#if defined(_WIN32)
+ int errNumber = GetLastError();
#else
- s << strerror(x);
+ int errNumber = errno;
#endif
- return s.str();
+ return {errNumber, errnoWithDescription(errNumber)};
}
void logContext(const char* errmsg) {
diff --git a/src/mongo/util/log.h b/src/mongo/util/log.h
index b0f53a30b87..82a78b3cf99 100644
--- a/src/mongo/util/log.h
+++ b/src/mongo/util/log.h
@@ -217,6 +217,7 @@ extern Tee* const warnings; // Things put here go in serverStatus
extern Tee* const startupWarningsLog; // Things put here get reported in MMS
std::string errnoWithDescription(int errorcode = -1);
+std::pair<int, std::string> errnoAndDescription();
/**
* Write the current context (backtrace), along with the optional "msg".
diff --git a/src/mongo/util/processinfo.cpp b/src/mongo/util/processinfo.cpp
index 5a0e8dc798c..8afcb2f0eeb 100644
--- a/src/mongo/util/processinfo.cpp
+++ b/src/mongo/util/processinfo.cpp
@@ -58,6 +58,15 @@ public:
path = p;
ofstream out(path.c_str(), ios_base::out);
out << ProcessId::getCurrent() << endl;
+ if (!out.good()) {
+ auto errAndStr = errnoAndDescription();
+ if (errAndStr.first == 0) {
+ log() << "ERROR: Cannot write pid file to " << path
+ << ": Unable to determine OS error";
+ } else {
+ log() << "ERROR: Cannot write pid file to " << path << ": " << errAndStr.second;
+ }
+ }
return out.good();
}
@@ -65,11 +74,7 @@ public:
} pidFileWiper;
bool writePidFile(const string& path) {
- bool e = pidFileWiper.write(path);
- if (!e) {
- log() << "ERROR: Cannot write pid file to " << path << ": " << strerror(errno);
- }
- return e;
+ return pidFileWiper.write(path);
}
ProcessInfo::SystemInfo* ProcessInfo::systemInfo = NULL;