Skip to content

#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