This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Fix bitfield incorrectly printing when field crosses a storage unit
Needs ReviewPublic

Authored by CharKeaney on Nov 17 2022, 3:32 AM.

Details

Summary

This patch resolves an issue where bitfields will not be
printed correctly if a field crosses a storage unit.

The issue is caused by lldb internally storing bitfield
field's offsets as unsigned rather than signed values.
Negative offsets can be created when a field crosses a
storage unit.

The issue is resolved by changing lldb's internal representation
for bitfield field offsets to be stored using signed values.
Also, in the code responsible for extracting data for printing,
the mechanism must be changed such that it can handle negative
offsets appropriately.

This patch includes a test case to test that the issue is resolved.

Diff Detail

Event Timeline

CharKeaney created this revision.Nov 17 2022, 3:32 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 17 2022, 3:32 AM
CharKeaney requested review of this revision.Nov 17 2022, 3:32 AM

Thanks for working on this. Due to llvm dev and vacation it took me a while to get to this.

lldb/test/API/commands/expression/expr-bitfield-on-boundary/Makefile
3

Add a comment here to explain why we need dwarf v2 specifically.

Which I think is because in v4 the encoding is done such that you won't get a negative offset?

lldb/test/API/commands/expression/expr-bitfield-on-boundary/main.cpp
3

Comment here that b is going across the byte boundary.

Maybe on the packed too, iirc without packed it would assign one whole byte to each of a and b.

9

b is going to be across the boundary, should we use a value that is also across the boundary?

Something like 9, so you have 0b1001. One bit on both sides of the boundary. Just in case lldb actually is dropping one side of the value and we aren't checking for that.

lldb/unittests/Platform/PlatformSiginfoTest.cpp
62

Are you reasonably sure you found all these cases? Don't want to loose the sign because of an implicit cast.

If not, -Wconversion is worth a go though lldb probably has hundreds of those already. Perhaps compare the number of those warnings before and after this change.

Note that this fixes https://github.com/llvm/llvm-project/issues/58769 in the commit message ("fixes #<the issue number>").

Also ping again! If you don't have the time to work on this in the near future, perhaps I can do the finishing touches and get it in (with you as co-author)? Would really like to see this issue fixed.

lldb/source/Utility/DataExtractor.cpp
588

Remove the {} when using single line ifs.

jwnhy added a subscriber: jwnhy.Mar 26 2023, 10:04 AM

Hi, guys, I have met this issue #61706.

The case I provided shows that even without DWARF v2, this problem still exists.

I wonder if such modification is really needed or not.

Also, I am not sure changing all these to int actually fixes the issue here.

In fact, in UpdateValue, the m_byte_offset also changed by the overhang_bytes in line .
For a bitfield not aligned to *type_bit_size, moving overhang_bytes will cause truncation in the bitfield.

#pragma pack(1)
struct  {
  signed f0 : 27;
  unsigned f5 : 30;
} g_96 = {5070, 1795821};
int main() {return 0;}

The structure in memory is represented as 0xdb37680013ce, adding m_byte_offset with overhang_bytes results in 0xdb37, with last five bits lost.

This patchset may fix the underflow problem of m_bitfield_bit_offset, but does not fix the truncation issue...

Not knowing there is a WIP patch, I have created another smaller patch, which just checks... (if it's not ok to hijack the thread, plz tell me...I am really newbie...)
https://reviews.llvm.org/D146919

I wonder if it's ok I take over this issue?