Skip to content

Commit 83643dd

Browse files
authored
[lldb] Improve error reporting in GetLocation_DW_OP_addr (#120162)
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 56cb554 commit 83643dd

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"
@@ -1704,7 +1705,7 @@ SymbolFileDWARF *SymbolFileDWARF::GetDIERefSymbolFile(const DIERef &die_ref) {
17041705
// We have a SymbolFileDWARFDebugMap, so let it find the right file
17051706
if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile())
17061707
return debug_map->GetSymbolFileByOSOIndex(*file_index);
1707-
1708+
17081709
// Handle the .dwp file case correctly
17091710
if (*file_index == DIERef::k_file_index_mask)
17101711
return GetDwpSymbolFile().get(); // DWP case
@@ -3506,17 +3507,20 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
35063507
// Check if the location has a DW_OP_addr with any address value...
35073508
lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
35083509
if (!location_is_const_value_data) {
3509-
bool op_error = false;
3510-
const DWARFExpression* location = location_list.GetAlwaysValidExpr();
3511-
if (location)
3512-
location_DW_OP_addr =
3513-
location->GetLocation_DW_OP_addr(location_form.GetUnit(), op_error);
3514-
if (op_error) {
3515-
StreamString strm;
3516-
location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
3517-
GetObjectFile()->GetModule()->ReportError(
3518-
"{0:x16}: {1} ({2}) has an invalid location: {3}", die.GetOffset(),
3519-
DW_TAG_value_to_name(die.Tag()), die.Tag(), strm.GetData());
3510+
if (const DWARFExpression *location =
3511+
location_list.GetAlwaysValidExpr()) {
3512+
if (auto maybe_location_DW_OP_addr =
3513+
location->GetLocation_DW_OP_addr(location_form.GetUnit())) {
3514+
location_DW_OP_addr = *maybe_location_DW_OP_addr;
3515+
} else {
3516+
StreamString strm;
3517+
location->DumpLocation(&strm, eDescriptionLevelFull, nullptr);
3518+
GetObjectFile()->GetModule()->ReportError(
3519+
"{0:x16}: {1} ({2}) has an invalid location: {3}: {4}",
3520+
die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.Tag(),
3521+
llvm::fmt_consume(maybe_location_DW_OP_addr.takeError()),
3522+
strm.GetData());
3523+
}
35203524
}
35213525
if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
35223526
is_static_lifetime = true;

0 commit comments

Comments
 (0)