> >( >( 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
> > []

Reply via email to