SUMMARY After valgrind upgrade to 3.22.0 it started failing with: valgrind: m_debuginfo/readelf.c:3394 (vgModuleLocal_read_elf_debug): Assertion 'di->rodata_size == a_shdr.sh_size' failed. when loading debuginfo file produced with mold 2.3.1. Binaries linked with bfd/lld work fine. valgrind 3.21.0 works fine. Also raised in mold under https://github.com/rui314/mold/issues/1139 as it's not clear who is to blame. STEPS TO REPRODUCE 1. Build sample c++ binary with debug symbols and link with mold: g++ -x c++ -g2 -fuse-ld=mold -o test - <<EOF #include <iostream> int main() { std::cout << "hello world" << std::endl; } EOF 2. Create debuginfo file: eu-strip -f test.di test 3. Run valgrind against binary: valgrind -v ./test OBSERVED RESULT valgrind fails: ... --413198-- Considering /home/users/builder/test.di .. --413198-- .. CRC is valid valgrind: m_debuginfo/readelf.c:3394 (vgModuleLocal_read_elf_debug): Assertion 'di->rodata_size == a_shdr.sh_size' failed. ... EXPECTED RESULT valgrind works fine
This changed fairly recently. If possible use Valgrind 3.21 while we look for a fix.
Does this occur when you don't strip the binary? The FreeBSD mold package is marked as broken due to an issue with strip (though that issue is with the mold exe).
I've done some debugging and possibly found the culprit. The assertion di->rodata_size == a_shdr.sh_size failed because left hand side was 8 while the other was 3. However in readelf output for both stripped binary and debuginfo file I see rodata size as 3. So assumed right hand side must be correct. So I've checked why valgrind thinks it's 8 for debuginfo file and found this: 2482 if (0 == VG_(strncmp)(name, ".rodata", 7)) { 2483 if ((inrx||inrw1) && !di->rodata_present) { /* first .rodata* */ 2484 di->rodata_svma = svma; 2485 di->rodata_avma = svma; 2486 di->rodata_size = size; 2487 di->rodata_debug_svma = svma; 2488 } else if ((inrx||inrw1) && di->rodata_present) { /* not first .rodata* */ 2489 Addr tmp = VG_ROUNDUP(di->rodata_size + di->rodata_svma, alyn); 2490 if (svma == tmp) { /* adjacent to previous .rodata* */ 2491 di->rodata_size = size + tmp - di->rodata_svma; 2492 } else { 2493 BAD(".rodata"); /* is OK, but we cannot handle multiple .rodata* */ 2494 } 2495 } https://sourceware.org/git/?p=valgrind.git;a=blob;f=coregrind/m_debuginfo/readelf.c;h=fb64ed9769d28e7f64762c8a34ebab8e353bc21f;hb=HEAD#l2482 It extends rodata_size with size of adjacent sections with name starting with ".rodata". Both debuginfo and stripped binary have adjacent .rodata and .rodata.cst4 sections with size 3 and 4 respectively which I believe after aligning make 8: [Nr] Name Type Address Off Size ES Flg Lk Inf Al [12] .rodata PROGBITS 000000000020059c 00059c 000003 00 A 0 0 1 [13] .rodata.cst4 PROGBITS 00000000002005a0 0005a0 000004 04 AM 0 0 4 I would assume same logic for accumulating size is not reflected here: https://sourceware.org/git/?p=valgrind.git;a=blob;f=coregrind/m_debuginfo/readelf.c;h=fb64ed9769d28e7f64762c8a34ebab8e353bc21f;hb=HEAD#l3362
Looks plausible. We might need to break out that FIND macro into an (inline) function if it also needs to be looking for contiguous rodata segments.
Confirmed on Fedora 38 with Valgrind 3.21 (works) and git head (fails).
commit 9ea4ae66707a4dcc6f4328e11911652e4418c585 (HEAD -> master, origin/users/paulf/try-bug476548, origin/master, origin/HEAD, bug476548) Author: Paul Floyd <pjfloyd@wanadoo.fr> Date: Sat Nov 18 08:49:34 2023 +0100 Bug 476548 - valgrind 3.22.0 fails on assertion when loading debuginfo file produced by mold
Confirmed the fix works fine. Thanks!
Found the same issue on Fedora 38 while loading /usr/lib64/ossl-modules/fips.so which has: [16] .rodata PROGBITS 0000000000105000 00105000 0000fa90 0 A 0 0 64 [17] .rodata1 PROGBITS 0000000000114aa0 00114aa0 00000020 0 A 0 0 32 commit 9ea4ae66707a4dcc6f4328e11911652e4418c585 fixes it We might want to backport this to the VALGRIND_3_22_BRANCH
Also pushed to VALGRIND_3_22_BRANCH as: commit 1d00e5ce0fb069911c4b525ec38289fb5d9021b0 Author: Paul Floyd <pjfloyd@wanadoo.fr> Date: Sat Nov 18 08:49:34 2023 +0100 Bug 476548 - valgrind 3.22.0 fails on assertion when loading debuginfo file produced by mold (cherry picked from commit 9ea4ae66707a4dcc6f4328e11911652e4418c585)