The mysterious case of unsupported DW_FORMs

I’m sharing some notes on a strange LLDB issue I hit locally, in case anyone else hits the same problem. The symptoms are symbols unexpectedly not working for some modules and/or warning messages complaining about “unsupported DW_FORMs”, ex:

warning: (x86_64) /lib/x86_64-linux-gnu/libz.so.1.2.8 unsupported DW_FORM values: 0x2 0x1b 0x1c 0x1d 0x1e 0x1f 0x21 0x22 0x23 0x24 0x25 0x26 0x27 0x28 0x29 … lots more values …

Tools like dwarfdump, objdump and realelf didn’t raise any complains about the affected symbols so the symbols themselves seemed fine. The LLDB warning was fired during parsing the .debug_abbrev section but dumping it showed nothing out of the ordinary(*)

The first hint that the problem was on the LLDB/LLVM side came from llvm-dwarfdump:

.debug_info contents:
error: failed to decompress ‘.debug_aranges’, zlib is not available
error: failed to decompress ‘.debug_info’, zlib is not available
error: failed to decompress ‘.debug_abbrev’, zlib is not available

Sure enough, the sections were compressed. LLDB tried to decompress, but when failed to do so it carried on returning and alter attempting to parse the compressed bytes as is.

Why weren’t my local LLVM & LLDB builds able to decompress the sections? CMake! Apparently the project files didn’t get correctly regenerated and my CMakeCache.txt had an unfortunate set of flags:

LLVM_ENABLE_ZLIB:BOOL=ON (great!)
HAVE_LIBZ_ZLIB:INTERNAL= (empty, hmm…)

It should have something like this instead:

LLVM_ENABLE_ZLIB:BOOL=ON
HAVE_ZLIB_H:INTERNAL=1

So there you have it folks. If it doesn’t work, reboot regenerate your cmake projects and try again.

(*) none of the tools bothered to make a note that the sections are compressed (SHF_COMPRESSED)

Why weren’t my local LLVM & LLDB builds able to decompress the sections? CMake!

Remembering to delete CMakeCache.txt is usually the part I forget to do.

LLDB tried to decompress, but when failed to do so it carried on returning and alter attempting to parse the compressed bytes as is.

A section that is compressed but can’t be decompressed should be treated as corrupt/unparseable. That seems like an LLDB bug; do you have an account on the project bugzilla?

(*) none of the tools bothered to make a note that the sections are compressed (SHF_COMPRESSED)

That seems like a completely valid feature request. Again filing a bug would be the right tactic. I’m willing to do this one for you, if you don’t have a bugzilla account.

Thanks,

–paulr

Thanks Paul! I have a fix for the LLDB handling of compressed sections in an upcoming change (together with improved logging). The email was mostly in case some other poor soul hit the same problem (until I get a chance to commit the fixes)

(*) none of the tools bothered to make a note that the sections are compressed (SHF_COMPRESSED)
That seems like a completely valid feature request. Again filing a bug would be the right tactic. I’m willing to do this one for you, if you don’t have a bugzilla account.

I’ll open a request for llvm-dwarfdump. If you happen to be in touch with the developers of the other tools (readelf, objdump, dwarfdump) feel free to forward them the notes.

I posted this suggestion on dwarf-discuss, where I would hope various tool maintainers are watching.

The maintainer of dwarfdump says that a new version now “prints the type of compression and the compression factor for each compressed section that’s being reported.” Very small sections (< 100 bytes) tend to get larger, but he says he’s seeing nearly 10x compression factors on string sections. Other sections are in between these extremes.

Don’t know about the GNU tools (readelf, objdump).

Did you file a bug for llvm-dwarfdump? I haven’t noticed one.

–paulr

Great. Thanks for the reminder, here’s the llvm-dwarfdump bug