Skip to content

[utils] Fix DenseMap debugger printers for the packed used-bit array#201755

Merged
MaskRay merged 5 commits into
llvm:mainfrom
MaskRay:pr/gdb-lldb-densemap-usedbit
Jun 8, 2026
Merged

[utils] Fix DenseMap debugger printers for the packed used-bit array#201755
MaskRay merged 5 commits into
llvm:mainfrom
MaskRay:pr/gdb-lldb-densemap-usedbit

Conversation

@MaskRay
Copy link
Copy Markdown
Member

@MaskRay MaskRay commented Jun 5, 2026

DenseMap no longer use in-band sentinel keys. (#200595 and #201281).
Update the GDB pretty printer and LLDB data formatters to test the used
bit rather than comparing keys.

GDB: advancePastEmptyBuckets relied on DenseMapInfo::getEmptyKey(), which
could not be evaluated in GDB and so was disabled, leaving the printer to
emit empty and erased buckets. It now walks bucket indices and skips any
whose used bit is clear.

LLDB: DenseMapSynthetic used a key-uniqueness heuristic to guess which
buckets were live, which mishandled a lone erased bucket (hence the
former tombstones=1 summary note). It now reads the used array directly,
so erased entries are skipped exactly. NumTombstones no longer exists, so
drop it from the summary.

Written by Claude Opus 4.8

DenseMap no longer use in-band sentinel keys. (llvm#200595 and llvm#201281).
Update the GDB pretty printer and LLDB data formatters to test the used
bit rather than comparing keys.

GDB: advancePastEmptyBuckets relied on DenseMapInfo::getEmptyKey(), which
could not be evaluated in GDB and so was disabled, leaving the printer to
emit empty and erased buckets. It now walks bucket indices and skips any
whose used bit is clear.

LLDB: DenseMapSynthetic used a key-uniqueness heuristic to guess which
buckets were live, which mishandled a lone erased bucket (hence the
former tombstones=1 summary note). It now reads the used array directly,
so erased entries are skipped exactly. NumTombstones no longer exists, so
drop it from the summary.

Written by Claude Opus 4.8
@MaskRay MaskRay requested a review from aengelke June 5, 2026 05:59
@MaskRay
Copy link
Copy Markdown
Member Author

MaskRay commented Jun 5, 2026

test scripts

set -e
SRC=/home/ray/llvm
LLDB=/tmp/Rel/bin/lldb
MC=/tmp/Debug/bin/llvm-mc
ASM=/tmp/t/densemap_mc.s

cat > "$ASM" <<'ASMEOF'
        .text
        .globl  foo
foo:
1:      nop
        jmp     1b
2:      nop
        jmp     2f
1:      nop
        jmp     1b
2:      nop
3:      nop
        jmp     3b
ASMEOF

"$LLDB" -b \
  -o "command script import $SRC/llvm/utils/lldbDataFormatters.py" \
  -o "breakpoint set --name llvm::MCAssembler::layout" \
  -o "run -filetype=obj -o /tmp/t/densemap_mc.o $ASM" \
  -o "script print('=== MCContext::Instances / LocalSymbols ===')" \
  -o "frame variable this->Context.Instances this->Context.LocalSymbols" \
  -o "kill" \
  -o "quit" \
  "$MC" 2>&1
set -e
SRC=/home/ray/llvm
MC=/tmp/Debug/bin/llvm-mc
ASM=/tmp/t/densemap_mc.s

cat > "$ASM" <<'ASMEOF'
        .text
        .globl  foo
foo:
1:      nop
        jmp     1b
2:      nop
        jmp     2f
1:      nop
        jmp     1b
2:      nop
3:      nop
        jmp     3b
ASMEOF

cat > /tmp/t/_gdb_cmds.gdb <<GDB
set pagination off
set breakpoint pending on
source $SRC/llvm/utils/gdb-scripts/prettyprinters.py
break llvm::MCAssembler::layout
run
echo \n=== MCContext::Instances (DenseMap<unsigned, MCLabel*>) ===\n
print Context.Instances
echo \n=== MCContext::LocalSymbols (DenseMap<pair<unsigned,unsigned>, MCSymbol*>) ===\n
print Context.LocalSymbols
kill
quit
GDB

# -nx: skip ~/.gdbinit (which may already source prettyprinters.py).
gdb -nx -q -batch -x /tmp/t/_gdb_cmds.gdb \
  --args "$MC" -filetype=obj -o /tmp/t/densemap_mc.o "$ASM"

Copy link
Copy Markdown
Contributor

@aengelke aengelke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok? I never used these (and also never wrote debugger printers myself), so I'm probably not the best person to review this...

Comment on lines 493 to +496
for index in range(num_buckets):
bucket = buckets.GetValueForExpressionPath(f"[{index}]")
key = bucket.GetChildAtIndex(0)
key_buckets[str(key.data)].append(index)

# Heuristic: This is not a multi-map, any repeated (non-unique) keys are
# either the the empty key or the tombstone key. Populate child_buckets
# with the indexes of entries containing unique keys.
for indexes in key_buckets.values():
if len(indexes) == 1:
self.child_buckets.append(indexes[0])
word = used.GetValueForExpressionPath(f"[{index >> 5}]").unsigned
if (word >> (index & 31)) & 1:
self.child_buckets.append(index)
Copy link
Copy Markdown
Contributor

@kastiglione kastiglione Jun 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tested it with the updated DenseMap, but I suggest avoiding calling GetValueForExpressionPath("[N]") 32 times for each N, by doing something like:

used_data = used.GetPointeeData(0, num_buckets // 32)
for word_idx, word in enumerate(used_data.uint32):
    for bit in range(32):
        if (word >> bit) & 1:
            self.child_buckets.append(word_idx * 32 + bit)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx for the suggestion! Changed num_buckets // 32 to (N+31)//32, since the number of buckets can be 4/8/16, smaller than 32.

@MaskRay MaskRay requested a review from kastiglione June 7, 2026 19:06
Comment thread llvm/utils/lldbDataFormatters.py Outdated
Copy link
Copy Markdown
Contributor

@kastiglione kastiglione left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the lldb formatter. Thank you.

@MaskRay MaskRay merged commit aec0da1 into llvm:main Jun 8, 2026
7 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants