> >( >( so what's going on here > > the latest information shows that some non-numeric data is being > parsed as a number ... maybe a wrong link pointer is being placed, > like maybe a length field is being written as a pointer who knows > > the two regions of interest seem separate for me. maybe i can ferry > enough information from one to another to discern a cause
i got a reprieve i can hold them near each other a little > > > (Pdb) list > > > 31 addr8 = memoryview(id).cast('Q')[0] > > > 32 l8 = max((self.q[addr8]+self.idsize-1)//self.idsize,1) + 1 > > > 33 self.q[addr8] = self.q[0] > > > 34 self.q[addr8+1] = l8 > > > 35 self.q[0] = addr8 > > > 36 -> self.fsck() > > > 37 def alloc(self, data, replacing=[]): > > > 38 self.fsck() > > > 39 l8 = max((len(data)+self.idsize-1)//self.idsize,1) + 1 > > > 40 addr8 = 0 > > > 41 assert self.q[addr8] != 0 > > > (Pdb) p addr8 > > > 1 > > > (Pdb) p id > > > b'\x01\x00\x00\x00\x00\x00\x00\x00' so this is what was deallocated. there was an allocated region at 0x1<<3 ... i think? [.. addr8 = memoryview(id).cast('Q')[0] ...] yeah the id is an address in quadwords. now below i didn't see a region starting at 0x1 in the regions list. :/ [scrolls down] oh no wait there totally was one :D :s ok so here ummm it's working on address 1 quadwords O_O O_O O_O > > > (Pdb) p self.q[addr8] > > > 11 this is after address so this should be the link. it says the next one is the region at 11<<3. > > > (Pdb) p l8 > > > 4 this is the calculated length of the region in quadwords > > > (Pdb) p addr8 > > > 1 > > > (Pdb) p l8 > > > 4 > > > (Pdb) p self.w[addr8*self.idsize:addr8+self.idsize+4*self.idsize] > > > <memory at 0x7f0a3b9d9840> > > > (Pdb) p > > > self.w[addr8*self.idsize:addr8+self.idsize+4*self.idsize].tobytes() > > > b'\x0b\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00k > > > brown fox jum\x00\t' and here's the raw data of the region. 0x0b is 11, the link to the next deallocated region. 0x4 is the length of the region in quadwords -- 32 bytes. it looks reasonable at a glance but something obviously is wrong; while trying to sleep i was wondering maybe the l8 quantity is inconsistent. another thought is maybe quadwords vs raw lengths is inconsistent, or somehow elsewise a disalignment. but usually it's been because of a logic case i left out, like how the regions list isn't updated during shrink. > > > > > > the 'k brown fox jum' content looks believable. additionally, the fsck > > > prior to the deallocation passed [ :S ] > > > > (Pdb) down > > > /home/karl3/projects/rep/rep/i.py(114)fsck() > > -> assert l8 <= self.yq - addr8 > > (Pdb) list > > 109 passed_regions.append(region) > > 110 assert region[1] <= self.yq - addr8 > > 111 addr8 += region[1] > > 112 else: > > 113 l8 = > > max((self.q[addr8]+self.idsize-1)//self.idsize,1) + 1 > > 114 -> assert l8 <= self.yq - addr8 > > 115 addr8 += l8 > > 116 assert addr8 == self.yq > > 117 def shrink(self): > > 118 self.fsck() > > 119 unused = 0 > > (Pdb) p addr8 > > 4 so here we are at address 4, not address 1. glancing down to `p regions` below, address 4 .. hrm ... [ ... regions.append([addr8, self.q[addr8+1]]) ... ] ... there's no address 4. 4 is the length of address 1. so this might be a bug in fsck ??? ... 0442 regions[] only contains deallocated regions. this is a branch for an allocated region. it's like the region after region 1 ...? (shouldn't that be 5?) i'm closer !!!!! ummmmmmmmmmmmmm 0444 so regions contains a region starting at 1. additionally, passed_regions is empty. [this debugging session found left open it's slightly possible it came from a different codebase slightly, but it has the passed_regions local]. passed_regions is set when processing a deallocated region >( so i don't know why addr8 is 4 ... yet ! what i can do is simulate the behavior of the function. addr8 started at 1. YAY I FOUND A BUG !!!! yay bug :D the regions are sorted in reversal, likely with intent to pop things from it like a stack. but region[0] is checked instead of popping or using region[-1]. i modified the algorithm partly and didn't sufficiently propagate the changes. this does not fully explain the condition but it's part. it shows why passed_regions is empty. 0448 here's new lines: assert regions[-1][0] >= addr8 if regions[-1][0] == addr8: 0449 so i guess that what must have happened would have been uh l8 = max((self.q[addr8]+self.idsize-1)//self.idsize,1) + 1 address 1 would have been treated as allocated, and the value considered an allocated length. (11). uhh ? but addr8 isn't 11+1=12. it's 4 :/ uhhh hehe oh but it's converted ! (Pdb) p max((11+self.idsize-1)//self.idsize,1) + 1 3 there we go. 3+1==4. so we found the bug! this was the bug!! bug tracking is hard, little tiny footprints, but they're there ! > > (Pdb) p self.q[addr8] > > 30809871133208422 > > (Pdb) p l8 > > 3851233891651054 > > (Pdb) p regions > > [[11, 501], [1, 4]] > > (Pdb) p passed_regions > > []