Skip to content

Commit

Permalink
[lldb] Add support in Status::AsCString to retrieve win32 system erro…
Browse files Browse the repository at this point in the history
…r strings

Reviewers: rnk, zturner, aleksandr.urakov

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D53092

llvm-svn: 344798
  • Loading branch information
aaronsm committed Oct 19, 2018
1 parent d294b92 commit c3d447f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
29 changes: 28 additions & 1 deletion lldb/source/Utility/Status.cpp
Expand Up @@ -27,6 +27,9 @@
#include <mach/mach.h>
#endif

#ifdef _WIN32
#include <windows.h>
#endif
#include <stdint.h> // for uint32_t

namespace llvm {
Expand Down Expand Up @@ -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<llvm::StringError>(AsCString(),
llvm::inconvertibleErrorCode());
}
Expand All @@ -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
Expand All @@ -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;
}
Expand Down
23 changes: 23 additions & 0 deletions lldb/unittests/Utility/StatusTest.cpp
Expand Up @@ -10,6 +10,10 @@
#include "lldb/Utility/Status.h"
#include "gtest/gtest.h"

#ifdef _WIN32
#include <winerror.h>
#endif

using namespace lldb_private;
using namespace lldb;

Expand Down Expand Up @@ -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

0 comments on commit c3d447f

Please sign in to comment.