Skip to content

Commit 9637e92

Browse files
committed
[lldb] Improve error reporting in DWARFExpression::GetLocation_DW_OP_addr
Instead of simply raising an error flag, use an llvm::Expected to propagate a meaningful error to the caller, who can report it. rdar://139705570
1 parent 8f151f0 commit 9637e92

File tree

3 files changed

+32
-29
lines changed

3 files changed

+32
-29
lines changed

lldb/include/lldb/Expression/DWARFExpression.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lldb/Utility/Status.h"
1717
#include "lldb/lldb-private.h"
1818
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
19+
#include "llvm/Support/Error.h"
1920
#include <functional>
2021

2122
namespace lldb_private {
@@ -61,15 +62,11 @@ class DWARFExpression {
6162
/// The dwarf unit this expression belongs to. Only required to resolve
6263
/// DW_OP{addrx, GNU_addr_index}.
6364
///
64-
/// \param[out] error
65-
/// If the location stream contains unknown DW_OP opcodes or the
66-
/// data is missing, \a error will be set to \b true.
67-
///
6865
/// \return
6966
/// The address specified by the operation, if the operation exists, or
70-
/// LLDB_INVALID_ADDRESS otherwise.
71-
lldb::addr_t GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu,
72-
bool &error) const;
67+
/// an llvm::Error otherwise.
68+
llvm::Expected<lldb::addr_t>
69+
GetLocation_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu) const;
7370

7471
bool Update_DW_OP_addr(const plugin::dwarf::DWARFUnit *dwarf_cu,
7572
lldb::addr_t file_addr);

lldb/source/Expression/DWARFExpression.cpp

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,30 +343,32 @@ static lldb::offset_t GetOpcodeDataSize(const DataExtractor &data,
343343
}
344344
}
345345

346-
lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu,
347-
bool &error) const {
348-
error = false;
346+
llvm::Expected<lldb::addr_t>
347+
DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu) const {
349348
lldb::offset_t offset = 0;
350349
while (m_data.ValidOffset(offset)) {
351350
const uint8_t op = m_data.GetU8(&offset);
352351

353352
if (op == DW_OP_addr)
354353
return m_data.GetAddress(&offset);
354+
355355
if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) {
356-
uint64_t index = m_data.GetULEB128(&offset);
356+
const uint64_t index = m_data.GetULEB128(&offset);
357357
if (dwarf_cu)
358358
return dwarf_cu->ReadAddressFromDebugAddrSection(index);
359-
error = true;
360-
break;
359+
return llvm::createStringError("cannot evaluate %s without a DWARF unit",
360+
DW_OP_value_to_name(op));
361361
}
362+
362363
const lldb::offset_t op_arg_size =
363364
GetOpcodeDataSize(m_data, offset, op, dwarf_cu);
364-
if (op_arg_size == LLDB_INVALID_OFFSET) {
365-
error = true;
366-
break;
367-
}
365+
if (op_arg_size == LLDB_INVALID_OFFSET)
366+
return llvm::createStringError("cannot get opcode data size for %s",
367+
DW_OP_value_to_name(op));
368+
368369
offset += op_arg_size;
369370
}
371+
370372
return LLDB_INVALID_ADDRESS;
371373
}
372374

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/Support/Casting.h"
1515
#include "llvm/Support/FileUtilities.h"
1616
#include "llvm/Support/Format.h"
17+
#include "llvm/Support/FormatAdapters.h"
1718
#include "llvm/Support/Threading.h"
1819

1920
#include "lldb/Core/Module.h"
@@ -1705,7 +1706,7 @@ SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) {
17051706
// We have a SymbolFileDWARFDebugMap, so let it find the right file
17061707
if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())
17071708
return debug_map->GetSymbolFileByOSOIndex(*file_index);
1708-
1709+
17091710
// Handle the .dwp file case correctly
17101711
if (*file_index == DIERef::k_file_index_mask)
17111712
return GetDwpSymbolFile().get(); // DWP case
@@ -3539,17 +3540,20 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
35393540
// Check if the location has a DW_OP_addr with any address value...
35403541
lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
35413542
if (!location_is_const_value_data) {
3542-
bool op_error = false;
3543-
const DWARFExpression* location = location_list.GetAlwaysValidExpr();
3544-
if (location)
3545-
location_DW_OP_addr =
3546-
location->GetLocation_DW_OP_addr(location_form.GetUnit(), op_error);
3547-
if (op_error) {
3548-
StreamString strm;
3549-
location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
3550-
GetObjectFile()->GetModule()->ReportError(
3551-
"{0:x16}: {1} ({2}) has an invalid location: {3}", die.GetOffset(),
3552-
DW_TAG_value_to_name(die.Tag()), die.Tag(), strm.GetData());
3543+
if (const DWARFExpression *location =
3544+
location_list.GetAlwaysValidExpr()) {
3545+
if (auto maybe_location_DW_OP_addr =
3546+
location->GetLocation_DW_OP_addr(location_form.GetUnit())) {
3547+
location_DW_OP_addr = *maybe_location_DW_OP_addr;
3548+
} else {
3549+
StreamString strm;
3550+
location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
3551+
GetObjectFile()->GetModule()->ReportError(
3552+
"{0:x16}: {1} ({2}) has an invalid location: {3}: {4}",
3553+
die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),
3554+
llvm::fmt_consume(maybe_location_DW_OP_addr.takeError()),
3555+
strm.GetData());
3556+
}
35533557
}
35543558
if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
35553559
is_static_lifetime = true;

0 commit comments

Comments
 (0)