llvm / llvm/llvm-project

[lldb] lldb should reject invalid DW_OP_mod results instead of continuing with a void Scalar

Open Beginner friendly
#208,433 1 comment 0 reactions 0 assignees View on GitHub
accepts-invalid lldb
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

LLDB's `DW_OP_mod` evaluator stores the result of `Scalar::operator%` back onto the DWARF stack without checking whether it is valid. When the modulo is undefined — for example a zero divisor, which the accepted [DWARF issue 250924.2](https://dwarfstd.org/issues/250924.2.html) clarifies should raise an error, like division — `operator%` returns a `Scalar` of type `e_void`, and evaluation continues with that invalid entry on the stack. Later opcodes can then consume or discard it (e.g. `DW_OP_drop`), so the invalid intermediate is silently absorbed instead of being reported where it arose.

## Source Evidence

`operator%` (in `Scalar.cpp`) returns a void `Scalar` when the modulo is undefined (zero divisor, or operands that do not promote to an integer):

```cpp
const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) {
Scalar result;
if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
if (!rhs.IsZero() && result.m_type == Scalar::e_int) {
result.m_integer = lhs.m_integer % rhs.m_integer;
return result;
}
}
result.m_type = Scalar::e_void;
return result;
}
```

The `DW_OP_mod` handler (in `DWARFExpression.cpp`) stores that result with no validity check:

```cpp
case DW_OP_mod:
tmp = stack.back();
stack.pop_back();
stack.back().GetScalar() = stack.back().GetScalar() % tmp.GetScalar();
break;
```

The neighbouring `DW_OP_div` handler, by contrast, guards both the zero divisor and the result validity:

```cpp
case DW_OP_div: {
tmp = stack.back();
if (tmp.GetScalar().IsZero())
return llvm::createStringError("divide by zero");
...
stack.back() = dividend / divisor;
if (!stack.back().GetScalar().IsValid())
return llvm::createStringError("divide failed");
} break;
```

`DW_OP_shr` and `DW_OP_plus_uconst` likewise return an evaluator error on failure. `DW_OP_mod` is the outlier that keeps the invalid `Scalar` and keeps going.

Contributor guide

Open the contributing guide

Research direction

Start with the DW_OP_mod handler in DWARFExpression.cpp and Scalar::operator% in Scalar.cpp, then compare the neighbouring DW_OP_div error checks. Done means invalid modulo results, including a zero divisor, produce an evaluator error instead of leaving a void Scalar on the DWARF stack and continuing.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers, devtools
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.