Skip to content

Commit

Permalink
[lldb] Avoid unhandled Error in TypeSystemMap::GetTypeSystemForLanguage
Browse files Browse the repository at this point in the history
When assertions are turned off, the `llvm::Error` value created at the
start of this function is overwritten using the move-assignment
operator, but the success value is never checked. Whenever a TypeSystem
cannot be found or created, this can lead to lldb core dumping with:

    Program aborted due to an unhandled Error:
    Error value was Success. (Note: Success values must still be checked prior to being destroyed).

Fix this by not creating a `llvm::Error` value in advance, and directly
returning the result of `llvm::make_error` instead, whenever an error is
encountered.

See also: <https://bugs.freebsd.org/253881> and
<https://bugs.freebsd.org/257829>.

Reviewed By: teemperor

Differential Revision: https://reviews.llvm.org/D108088
  • Loading branch information
DimitryAndric committed Aug 16, 2021
1 parent d6fe8d3 commit 5033f07
Showing 1 changed file with 38 additions and 52 deletions.
90 changes: 38 additions & 52 deletions lldb/source/Symbol/TypeSystem.cpp
Expand Up @@ -223,70 +223,56 @@ void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
lldb::LanguageType language,
llvm::Optional<CreateCallback> create_callback) {
llvm::Error error = llvm::Error::success();
assert(!error); // Check the success value when assertions are enabled
std::lock_guard<std::mutex> guard(m_mutex);
if (m_clear_in_progress) {
error = llvm::make_error<llvm::StringError>(
if (m_clear_in_progress)
return llvm::make_error<llvm::StringError>(
"Unable to get TypeSystem because TypeSystemMap is being cleared",
llvm::inconvertibleErrorCode());
} else {
collection::iterator pos = m_map.find(language);
if (pos != m_map.end()) {
auto *type_system = pos->second.get();
if (type_system) {
llvm::consumeError(std::move(error));
return *type_system;
}
error = llvm::make_error<llvm::StringError>(
"TypeSystem for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist",
llvm::inconvertibleErrorCode());
return std::move(error);
}

for (const auto &pair : m_map) {
if (pair.second && pair.second->SupportsLanguage(language)) {
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
m_map[language] = pair.second;
if (pair.second.get()) {
llvm::consumeError(std::move(error));
return *pair.second.get();
}
error = llvm::make_error<llvm::StringError>(
"TypeSystem for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist",
llvm::inconvertibleErrorCode());
return std::move(error);
}
}
collection::iterator pos = m_map.find(language);
if (pos != m_map.end()) {
auto *type_system = pos->second.get();
if (type_system)
return *type_system;
return llvm::make_error<llvm::StringError>(
"TypeSystem for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist",
llvm::inconvertibleErrorCode());
}

if (!create_callback) {
error = llvm::make_error<llvm::StringError>(
"Unable to find type system for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)),
llvm::inconvertibleErrorCode());
} else {
// Cache even if we get a shared pointer that contains a null type system
// back
TypeSystemSP type_system_sp = (*create_callback)();
m_map[language] = type_system_sp;
if (type_system_sp.get()) {
llvm::consumeError(std::move(error));
return *type_system_sp.get();
}
error = llvm::make_error<llvm::StringError>(
for (const auto &pair : m_map) {
if (pair.second && pair.second->SupportsLanguage(language)) {
// Add a new mapping for "language" to point to an already existing
// TypeSystem that supports this language
m_map[language] = pair.second;
if (pair.second.get())
return *pair.second.get();
return llvm::make_error<llvm::StringError>(
"TypeSystem for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist",
llvm::inconvertibleErrorCode());
}
}

return std::move(error);
if (!create_callback)
return llvm::make_error<llvm::StringError>(
"Unable to find type system for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)),
llvm::inconvertibleErrorCode());

// Cache even if we get a shared pointer that contains a null type system
// back
TypeSystemSP type_system_sp = (*create_callback)();
m_map[language] = type_system_sp;
if (type_system_sp.get())
return *type_system_sp.get();
return llvm::make_error<llvm::StringError>(
"TypeSystem for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist",
llvm::inconvertibleErrorCode());
}

llvm::Expected<TypeSystem &>
Expand Down

0 comments on commit 5033f07

Please sign in to comment.