Apply upstream lldb fix for unhandled Error causing abort

Merge commit 5033f0793fe6 from llvm git (by Dimitry Andric):

  [lldb] Avoid unhandled Error in TypeSystemMap::GetTypeSystemForLanguage

  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

Reported by:	dmgk, ota@j.email.ne.jp
PR:		253881, 257829
MFC after:	3 days
This commit is contained in:
Dimitry Andric 2021-08-16 18:56:41 +02:00
parent c3295781fd
commit c1a540709a

View File

@ -224,62 +224,32 @@ void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage( llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
lldb::LanguageType language, lldb::LanguageType language,
llvm::Optional<CreateCallback> create_callback) { 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); std::lock_guard<std::mutex> guard(m_mutex);
if (m_clear_in_progress) { if (m_clear_in_progress)
error = llvm::make_error<llvm::StringError>( return llvm::make_error<llvm::StringError>(
"Unable to get TypeSystem because TypeSystemMap is being cleared", "Unable to get TypeSystem because TypeSystemMap is being cleared",
llvm::inconvertibleErrorCode()); 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) { collection::iterator pos = m_map.find(language);
if (pair.second && pair.second->SupportsLanguage(language)) { if (pos != m_map.end()) {
// Add a new mapping for "language" to point to an already existing auto *type_system = pos->second.get();
// TypeSystem that supports this language if (type_system)
m_map[language] = pair.second; return *type_system;
if (pair.second.get()) { return llvm::make_error<llvm::StringError>(
llvm::consumeError(std::move(error)); "TypeSystem for language " +
return *pair.second.get(); llvm::StringRef(Language::GetNameForLanguageType(language)) +
} " doesn't exist",
error = llvm::make_error<llvm::StringError>( llvm::inconvertibleErrorCode());
"TypeSystem for language " + }
llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist",
llvm::inconvertibleErrorCode());
return std::move(error);
}
}
if (!create_callback) { for (const auto &pair : m_map) {
error = llvm::make_error<llvm::StringError>( if (pair.second && pair.second->SupportsLanguage(language)) {
"Unable to find type system for language " + // Add a new mapping for "language" to point to an already existing
llvm::StringRef(Language::GetNameForLanguageType(language)), // TypeSystem that supports this language
llvm::inconvertibleErrorCode()); m_map[language] = pair.second;
} else { if (pair.second.get())
// Cache even if we get a shared pointer that contains a null type system return *pair.second.get();
// back return llvm::make_error<llvm::StringError>(
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>(
"TypeSystem for language " + "TypeSystem for language " +
llvm::StringRef(Language::GetNameForLanguageType(language)) + llvm::StringRef(Language::GetNameForLanguageType(language)) +
" doesn't exist", " doesn't exist",
@ -287,7 +257,23 @@ llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
} }
} }
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 &> llvm::Expected<TypeSystem &>