#491 PoolAllocator not 64 bit clean
Metadata
Property | Value |
---|---|
Reported by | Markus Blatt (markus@dr-blatt.de) |
Reported at | Feb 2, 2009 12:20 |
Type | Bug Report |
Version | Git (pre2.4) [autotools] |
Operating System | Linux 64bit |
Last edited by | Markus Blatt (markus@dr-blatt.de) |
Last edited at | Dec 3, 2009 16:57 |
Closed by | Markus Blatt (markus@dr-blatt.de) |
Closed at | Dec 3, 2009 16:57 |
Closed in version | Unknown |
Resolution | Implemented |
Comment | with rev. 5730 |
Description
If the SLList ist used with the poolallocator in sllistest it fails:
When using std::allocator the test works fine.
Quoting from Elias mail:
ich bin mittlerweile auf (64bit-) Gentoo Linux mit gcc 4.3.3 unterwegs und in dune-common auf einen Test Fehler gestossen. Weil es sich um sllisttest handelt, und offenbar nie jemand ausser dir daran Hand angelegt hat, wende ich mich direkt an dich.
Der Fehler lautet
test insert sllisttest: ../../dune/common/sllist.hh:690: void Dune::SLList<T, A>::insertAfter(Dune::SLList<T, A>::Element*, const T&) [with T = int, A = Dune::PoolAllocator<int, 8176ul>]: Assertion `!tail_->next_' failed. Aborted
Ich hab versucht, das Problem zu finden, bislang aber ohne Erfolg. Der Fehler liegt offenbar in den Zeilen
iter=alist.beginModify(); iter.insert(5);
also sllisttest.cc:274. Mein Hauptproblem ist (ich hab zuvor nur C-, nicht aber C++-Code mit GDB durchforstet), dass es (wegen inlining?) mir nicht moeglich ist, lokale Variablen in Methoden auszugeben (im Gegensatz zu Membervariablen -- ohne die waer ich nichteinmal bis hier gekommen). CXXFLAGS='-O0 -g3 -fno-inline' hat nicht geholfen.
Zu diesem Zweck hab ich mir ein GDB Macro geschrieben
define dune-print-sllist set $size = $arg0.size_ set $i = $size set $head_ptr = &$arg0.beforeHead_
look out for at most 5 trailing elements, avoids infinite loops
but lets us look further than the specified size
while $head_ptr != 0 && $i > -5 if $i == -1 printf "warning, trailing elementsn" end print $head_ptr->item_ set $head_ptr = $head_ptr->next_ set $i-- end end
document dune-print-sllist print the given Dune::SLList element-wise end
das ich mittels
define hook-stop dune-print-sllist alist end
nach jedem "next" laufen lasse. Das laesst die Aussage zu, dass
alist.push_back(3)
und
iter.insert(7)
genau tun, was sie sollen. Danach sieht die Aussage von dune-print-sllist wie folgt aus:
$316 = 0 $317 = 7 $318 = 3
(dafuer, dass ich beforeHead_.item_ mit ausgebe, gibt es keinen besonderen Grund).
Etwas schief geht nun in
inline void SLList<T,A>::insertAfter(Element* current, const T& item)
wo nach den Zeilen
// Allocate space
current->next_ = allocator_.allocate(1, 0);
// Use copy constructor to initialize memory
::new(static_cast<void*>(&(current->next_->item_))) T(item);
die 7 verschwunden ist:
$319 = 0 $320 = 3
dann wieder auftaucht
(gdb) next $321 = 0 $322 = 3 $323 = 7 warning, trailing elements $324 = 3 $325 = 7 $326 = 3 $327 = 7
und die 3 schliesslich durch die 5 ersetzt wird:
(gdb) $342 = 0 $343 = 5 $344 = 7 warning, trailing elements $345 = 5 $346 = 7 $347 = 5 $348 = 7
Wenige Zeilen weiter unten fliegt dann
assert(!tail_->next_);
wegen
(gdb) print alist.tail_.item_ $476 = 5 (gdb) print alist.tail_.next_->item_ $477 = 7