New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CodeViewWidget: Fix undefined behavior when centered around address 0 #10268
Conversation
|
This is still broken for the case Which will then result in an out-of-bounds vector access in Maybe just clamp the first/last visible rows too... The wrap-around behavior is questionable but since this didn't work before either and is extremely unlikely to happen in practice it's probably fine to generate bad arrows. |
|
Fixed. Here's the result with this: m_branches.emplace_back(CodeViewBranch{0xffffffe0, 0xffffffe4, 0, false});
m_branches.emplace_back(CodeViewBranch{0xffffffec, 0xffffffe8, 0, false});
m_branches.emplace_back(CodeViewBranch{0x10, 0xfffffff0, 0, false});
m_branches.emplace_back(CodeViewBranch{0xfffffff4, 0x0c, 0, false});
m_branches.emplace_back(CodeViewBranch{0x14, 0x18, 0, false});
m_branches.emplace_back(CodeViewBranch{0x20, 0x1c, 0, false}); |
92986d3
to
b091b63
Compare
| const bool lower_in_range = first_addr <= arrow_addr_lower && arrow_addr_lower <= last_addr; | ||
| const bool upper_in_range = first_addr <= arrow_addr_upper && arrow_addr_upper <= last_addr; | ||
| const bool is_visible = lower_in_range || upper_in_range; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd replace this with is_visible = std::max(arrow_addr_lower, first_addr) <= std::min(arrow_addr_upper, last_addr) -- basically just a range overlap check. That way we properly handle cases where neither arrow end is inside the view.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed, but note that the way m_branches is currently calculated means that this doesn't come up in practice (it only contains branches where the source is visible; it doesn't contain ones where the destination is visible but not the source, and it doesn't contain ones where neither of them are visible). That might be worth changing in the future, but the current implementation doesn't handle it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
True! But if someone were to change this in the future so, say, all branches of the currently visible function(s) were checked, it'll be nice that this works already.
|
Otherwise this seems good now. |
b091b63
to
5bcbc8f
Compare


Scrolling defaults to being centered around address 0x00000000, which means addresses before the start are visible (e.g. 0xffffffa8 - 0x00000050). However, std::clamp has undefined behavior if the low value is greater than the high value (in MSVC, this results in a failed assertion in debug mode, and returning the max value in release mode (I think).) This essentially means that using a debug build with the code view widget enabled results in a crash every time.
The new behavior should work correctly, though I'm not 100% sure it gives correct results for a branch from, say, address 0x10 to address 0xfffffff0. That's not something that happens often in practice, so I'm not too worried about it.