https://bugs.kde.org/show_bug.cgi?id=520170

--- Comment #5 from Paul Floyd <[email protected]> ---
For Claude's analysis, this is the interesting bit:

===
**Dealloc side:** vte emits `call _ZdlPvm@plt`. The thunk chain is
`_ZdlPvm → _ZdlPv → free`. On fdo-sdk 25.08 glibc (≥ 2.41 exports
`free_sized`), `free` and `free_sized` share an implementation; valgrind's
scanner ends up tagging the call via the `free_sized` intercept →
`MC_AllocMalloc`. This is the `free_sized (vg_replace_malloc.c:996)` frame
in the report.

**Alloc side:** report shows the call going through the `_Znam` intercept
(line 717) even though the source calls `::operator new`. Most plausible
cause: fdo-sdk libstdc++ is built with link-time ICF collapsing `_Znwm` and
`_Znam` to one address; valgrind picks `_Znam` as the canonical redirect.
On my Fedora 43 host they're at distinct addresses (0x1f3e0 vs 0x1f440) so
I can't reproduce this side directly, but it's the only mechanism I can see
that produces the symptom from a `call _Znwm@plt`.

Result: alloc `MC_AllocNewVec` vs free `MC_AllocMalloc` → mismatch.
===

 `free` and `free_sized` share an implementation

I do not believe that is correct. Testing on Fedora 44
 nm /lib64/libc.so.6  | grep " free"
00000000000843f0 T free
0000000000084c60 W free_sized

This is just making a sibling call to free:
0000000000084c60 <free_sized>:
   84c60:       f3 0f 1e fa             endbr64
   84c64:       e9 97 bb f7 ff          jmp    800 <free@plt>
   84c69:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

In /lib64/libstdc++.so.6 all of the operator new and operator delete overloads
are global T symbols - no aliases.

nm -D /lib64/libstdc++.so.6 | grep _Zn
0000000000021340 T _Znam@@GLIBCXX_3.4
0000000000021350 T _ZnamRKSt9nothrow_t@@GLIBCXX_3.4
0000000000021410 T _ZnamSt11align_val_t@@CXXABI_1.3.11
0000000000021420 T _ZnamSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11
00000000000212e0 T _Znwm@@GLIBCXX_3.4
0000000000021320 T _ZnwmRKSt9nothrow_t@@GLIBCXX_3.4
0000000000021370 T _ZnwmSt11align_val_t@@CXXABI_1.3.11
00000000000213f0 T _ZnwmSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11

nm -D /lib64/libstdc++.so.6 | grep _Zd
000000000001f310 T _ZdaPv@@GLIBCXX_3.4
000000000001f320 T _ZdaPvm@@CXXABI_1.3.9
0000000000021490 T _ZdaPvmSt11align_val_t@@CXXABI_1.3.11
000000000001f330 T _ZdaPvRKSt9nothrow_t@@GLIBCXX_3.4
0000000000021470 T _ZdaPvSt11align_val_t@@CXXABI_1.3.11
0000000000021480 T _ZdaPvSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11
000000000001f2e0 T _ZdlPv@@GLIBCXX_3.4
000000000001f2f0 T _ZdlPvm@@CXXABI_1.3.9
0000000000021460 T _ZdlPvmSt11align_val_t@@CXXABI_1.3.11
000000000001f300 T _ZdlPvRKSt9nothrow_t@@GLIBCXX_3.4
0000000000021440 T _ZdlPvSt11align_val_t@@CXXABI_1.3.11
0000000000021450 T _ZdlPvSt11align_val_tRKSt9nothrow_t@@CXXABI_1.3.11

The assembler for sized scalar delete:

0000000000008830 <_ZdlPvm@plt>:
    8830:       f3 0f 1e fa             endbr64
    8834:       ff 25 1e 44 2a 00       jmp    *0x2a441e(%rip)        # 2acc58
<_ZdlPvm@@CXXABI_1.3.9+0x28d968>
    883a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

that leads to a sibling call to plain scalar delete.

and sized vector delete:
000000000001f320 <_ZdaPvm@@CXXABI_1.3.9>:
   1f320:       f3 0f 1e fa             endbr64
   1f324:       e9 77 5c fe ff          jmp    4fa0 <_ZdaPv@plt>
   1f329:       0f 1f 80 00 00 00 00    nopl   0x0(%rax)

You gdb output is what I would expect. I still don't understand how the call to
_ZdlPvm (sized scalar operator delete) gets to free_sized. Valgrind should be
redirecting _ZdlPvm and using its own allocator, it should never reach glibc
free_sized.

Could you send the output of 
nm -D /lib64/libstdc++.so.6 | grep _Zn
nm -D /lib64/libstdc++.so.6 | grep _Zd
and
 nm /lib64/libc.so.6  | grep " free"
For the last one there are several functions that start with free, I'm only
interest in free and free_sized. Please change the path if you are not using
the system libc.so and libstdc__.so.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to