Hatte irgendwann Abends nebenher mal angefangen eine ArrayDeque zu implementieren. Tat in ein paar Tests, aber irgendwie nicht in einem mit 100 Elementen. Weil ich immer nur mit Compilerbugs konfrontiert bin, dachte ich aber irgendwie, der Code sei ok und der Compiler hat eine Macke. Gibt schon länger valgrind-Integration. Also valgrind angeschaut; sagt irgendwas von write. Ratlos gesucht, nichts gefunden, was auf einen Bug hindeutet. Naja wenn man sich das anschaut, sieht das so aus:
Code: Alles auswählen
==55238== Command: ./main.1.tests
==55238==
==55238== Invalid write of size 8
==55238== at 0x401301: ??? (tyr.container/ArrayDeque.tyr:112)
==55238== by 0x404701: main.T test loop (main/main.tyr:15)
==55238== by 0x404701: main (unkown:0)
==55238== Address 0x4a5d0f8 is 8 bytes after a block of size 64 alloc'd
==55238== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55238== by 0x4046D1: tyr.container.ArrayDeque[tyr.lang.String].new(tyr.container.ArrayDeque[tyr.lang.String],tyr.lang.container.index_t):tyr.lang.void (tyr.container/ArrayDeque.tyr:52)
==55238== by 0x4046D1: main.T test loop (main/main.tyr:9)
==55238== by 0x4046D1: main (unkown:0)
==55238==
==55238== Invalid write of size 8
==55238== at 0x401301: ??? (tyr.container/ArrayDeque.tyr:112)
==55238== by 0x40470F: main.T test loop (main/main.tyr:16)
==55238== by 0x40470F: main (unkown:0)
==55238== Address 0x4a5d100 is 16 bytes after a block of size 64 alloc'd
==55238== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==55238== by 0x4046D1: tyr.container.ArrayDeque[tyr.lang.String].new(tyr.container.ArrayDeque[tyr.lang.String],tyr.lang.container.index_t):tyr.lang.void (tyr.container/ArrayDeque.tyr:52)
==55238== by 0x4046D1: main.T test loop (main/main.tyr:9)
==55238== by 0x4046D1: main (unkown:0)
==55238==
whob==55238==
==55238== HEAP SUMMARY:
==55238== in use at exit: 0 bytes in 0 blocks
==55238== total heap usage: 3 allocs, 3 frees, 1,128 bytes allocated
==55238==
==55238== All heap blocks were freed -- no leaks are possible
Wenn man jetzt einen Schritt zurücktritt stellt man natürlich fest, dass ich in den ArrayDeques das Problem habe, dass die validen Elemente über den Rand des backing Arrays hinaus an den Anfang wrappen. D.h. einfach data(end++) ist jetzt *nicht direkt* die richtige Implementierung für ein append.
Ich muss einfach mehr an mich und meine Tools glauben :-/
Was ich ehrlich gesagt nicht ganz verstehe, ist, warum der clang memory sanitizer nichts sinnvolles beizutragen hatte. Letztlich bedeutet das für das Projekt aber, dass ich die Check-Bounds-Optionen spätestens mit 0.9 reinbauen werde. Brauch dafür aber erstmal Exceptions. Und vielleicht freie Variablen in der Templatetyptheorie; muss ich mal schauen.