https://bugs.kde.org/show_bug.cgi?id=517126
Bug ID: 517126
Summary: Mismatched frees with ICF
Classification: Developer tools
Product: valgrind
Version First 3.27 GIT
Reported In:
Platform: unspecified
OS: All
Status: REPORTED
Severity: normal
Priority: NOR
Component: memcheck
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
ICF is Identical Code Folding, a feature available with lld and gold but not
GNU BFD ld.
With this feature the linker can eliminate functions that use identical machine
code. Unfortunately for us that can include overloads of operator delete.
I don't think that we can do anything about this. Could DWARF help? At the
moment I think that I'll just add a FAQ entry along the lines "don't use ICF,
if you must use it then either suppress any errors that it causes or use the
option --show-mismatched-frees=no".
Here is an example
#include <map>
#include <new>
#include <cstddef>
#include <iostream>
struct StuffA {
char* alignas(64) d;
StuffA() : d(new char[42]) {}
~StuffA() { delete [] d;}
StuffA(const StuffA& thing) {
d = new char[42];
}
StuffA& operator=(const StuffA& other) {
// do nothing, just pretend they were copied
return *this;
}
};
struct StuffB {
char* d;
StuffB() : d(new char[42]) {}
~StuffB() { delete [] d;}
StuffB(const StuffB& thing) {
d = new char[42];
}
StuffB& operator=(const StuffB& other) {
// do nothing, just pretend they were copied
return *this;
}
};
struct alignas(64) BigAligned {
int payload;
StuffA a;
BigAligned(int v = 0) : payload(v) {}
};
bool operator<(const BigAligned& a, const BigAligned& b) { return a.payload <
b.payload; }
struct Normal {
int payload;
StuffB b;
Normal(int v = 0) : payload(v) {}
};
bool operator<(const Normal& a, const Normal& b) { return a.payload <
b.payload; }
int main() {
std::map<BigAligned, BigAligned> m;
std::map<Normal, Normal> n;
// Insert some elements — std::map allocates nodes internally
for (int i = 0; i < 10; ++i) {
m.emplace(BigAligned{i}, BigAligned{i * 2});
}
// Insert some elements — std::map allocates nodes internally
for (int i = 0; i < 10; ++i) {
n.emplace(Normal{i}, Normal{i * 2});
}
// Erase elements — this forces std::map to call delete on node pointers
for (int i = 0; i < 10; ++i) {
m.erase(BigAligned{i});
}
// Erase elements — this forces std::map to call delete on node pointers
for (int i = 0; i < 10; ++i) {
n.erase(Normal{i});
}
return 0;
}
Compile with
g++ -std=c++20 -O2 -Wl,--icf=all map_aligned.cpp -o map_aligned -fuse-ld=lld -g
-Wl,-rpath,$HOME/tools/gcc/lib64 -static-libstdc++
That gives erorrs like
==2263== Mismatched free() / delete / delete []
==2263== at 0x404273C: operator delete[](void*) (vg_replace_malloc.c:1362)
==2263== by 0x22E812: deallocate (new_allocator.h:172)
==2263== by 0x22E812: deallocate (allocator.h:215)
==2263== by 0x22E812: deallocate (alloc_traits.h:649)
==2263== by 0x22E812: _M_put_node (stl_tree.h:1191)
==2263== by 0x22E812: _M_drop_node (stl_tree.h:1274)
==2263== by 0x22E812: _M_erase_aux (stl_tree.h:3116)
==2263== by 0x22E812: _M_erase_aux (stl_tree.h:3130)
==2263== by 0x22E812: erase (stl_tree.h:3141)
==2263== by 0x22E812: erase (stl_map.h:1159)
==2263== by 0x22E812: main (map_aligned.cpp:71)
==2263== Address 0x519e6e0 is 0 bytes inside a block of size 64 alloc'd
==2263== at 0x403CED8: operator new(unsigned long) (vg_replace_malloc.c:501)
==2263== by 0x22E213: allocate (new_allocator.h:151)
==2263== by 0x22E213: allocate (allocator.h:203)
==2263== by 0x22E213: allocate (alloc_traits.h:614)
==2263== by 0x22E213: _M_get_node (stl_tree.h:1170)
==2263== by 0x22E213: _M_create_node<Normal, Normal> (stl_tree.h:1253)
==2263== by 0x22E213: _Auto_node<Normal, Normal> (stl_tree.h:2285)
==2263== by 0x22E213: std::_Rb_tree_iterator<std::pair<Normal const, Normal>
> std::_Rb_tree<Normal, std::pair<Normal const, Normal>,
std::_Select1st<std::pair<Normal const, Normal> >, std::less<Normal>,
std::allocator<std::pair<Normal const, Normal> >
>::_M_emplace_hint_unique<Normal,
Normal>(std::_Rb_tree_const_iterator<std::pair<Normal const, Normal> >,
Normal&&, Normal&&) (stl_tree.h:3084)
==2263== by 0x22E605: emplace_hint<Normal, Normal> (stl_map.h:663)
==2263== by 0x22E605: emplace<Normal, Normal> (stl_map.h:624)
==2263== by 0x22E605: main (map_aligned.cpp:61)
(I tried to generate some mismatched aligned new [] / delete [] errors but no
luck).
--
You are receiving this mail because:
You are watching all bug changes.