From c3d447fe26f9bf742625f70feadd102c1eed0d99 Mon Sep 17 00:00:00 2001 From: Aaron Smith Date: Fri, 19 Oct 2018 18:58:24 +0000 Subject: [PATCH] [lldb] Add support in Status::AsCString to retrieve win32 system error strings Reviewers: rnk, zturner, aleksandr.urakov Subscribers: lldb-commits Differential Revision: https://reviews.llvm.org/D53092 llvm-svn: 344798 --- lldb/source/Utility/Status.cpp | 29 ++++++++++++++++++++++++++++- lldb/unittests/Utility/StatusTest.cpp | 23 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/lldb/source/Utility/Status.cpp b/lldb/source/Utility/Status.cpp index f6dc228..5caecc6 100644 --- a/lldb/source/Utility/Status.cpp +++ b/lldb/source/Utility/Status.cpp @@ -27,6 +27,9 @@ #include #endif +#ifdef _WIN32 +#include +#endif #include // for uint32_t namespace llvm { @@ -87,7 +90,8 @@ llvm::Error Status::ToError() const { if (Success()) return llvm::Error::success(); if (m_type == ErrorType::eErrorTypePOSIX) - return llvm::errorCodeToError(std::error_code(m_code, std::generic_category())); + return llvm::errorCodeToError( + std::error_code(m_code, std::generic_category())); return llvm::make_error(AsCString(), llvm::inconvertibleErrorCode()); } @@ -106,6 +110,23 @@ const Status &Status::operator=(const Status &rhs) { Status::~Status() = default; +#ifdef _WIN32 +static std::string RetrieveWin32ErrorString(uint32_t error_code) { + char *buffer = nullptr; + std::string message; + // Retrieve win32 system error. + if (::FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_MAX_WIDTH_MASK, + NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&buffer, 0, NULL)) { + message.assign(buffer); + ::LocalFree(buffer); + } + return message; +} +#endif + //---------------------------------------------------------------------- // Get the error value as a NULL C string. The error string will be fetched and // cached on demand. The cached error string value will remain until the error @@ -128,6 +149,12 @@ const char *Status::AsCString(const char *default_error_str) const { m_string = llvm::sys::StrError(m_code); break; + case eErrorTypeWin32: +#if defined(_WIN32) + m_string = RetrieveWin32ErrorString(m_code); +#endif + break; + default: break; } diff --git a/lldb/unittests/Utility/StatusTest.cpp b/lldb/unittests/Utility/StatusTest.cpp index b3f5182..4e0cfb9 100644 --- a/lldb/unittests/Utility/StatusTest.cpp +++ b/lldb/unittests/Utility/StatusTest.cpp @@ -10,6 +10,10 @@ #include "lldb/Utility/Status.h" #include "gtest/gtest.h" +#ifdef _WIN32 +#include +#endif + using namespace lldb_private; using namespace lldb; @@ -51,3 +55,22 @@ TEST(StatusTest, ErrorConversion) { EXPECT_TRUE(bool(foo)); EXPECT_EQ("foo", llvm::toString(std::move(foo))); } + +#ifdef _WIN32 +TEST(StatusTest, ErrorWin32) { + auto success = Status(NO_ERROR, ErrorType::eErrorTypeWin32); + EXPECT_STREQ(NULL, success.AsCString()); + EXPECT_FALSE(success.ToError()); + EXPECT_TRUE(success.Success()); + + auto s = Status(ERROR_ACCESS_DENIED, ErrorType::eErrorTypeWin32); + EXPECT_TRUE(s.Fail()); + EXPECT_STREQ("Access is denied. ", s.AsCString()); + + s.SetError(ERROR_IPSEC_IKE_TIMED_OUT, ErrorType::eErrorTypeWin32); + EXPECT_STREQ("Negotiation timed out ", s.AsCString()); + + s.SetError(16000, ErrorType::eErrorTypeWin32); + EXPECT_STREQ("unknown error", s.AsCString()); +} +#endif -- 2.7.4