[M3devel] help debugging Juno..sanity check?
Jay K
jay.krell at cornell.edu
Tue Sep 29 07:39:24 CEST 2009
oops, thanks, I forgot gc is compacting.
I don't see how to use a hardware breakpoint,
the corruption seems to always move around.
This is an attempt to set a hardware breakpoint programmatically based
on what the runtime addresses happen to be.
I do know these bytes are getting overwritten.
If I assert they are zero in Join, inevitably the assert fails.
I think I might try to vary the Juno pixmaps, see if the altered
data appears in the corruption, try to prove, as it appears,
that the corruption is pixmap data.
Thanks,
- Jay
From: hosking at cs.purdue.edu
To: jay.krell at cornell.edu
Date: Mon, 28 Sep 2009 10:04:55 -0400
CC: m3devel at elegosoft.com
Subject: Re: [M3devel] help debugging Juno..sanity check?
Huh? I don't understand the point of all of this. Threads can be moved by the GC, even if referenced from globals. The only way to prevent a thread moving is to keep a reference to it on some thread stack. (I still don't know what you are trying to achieve -- why not use a hardware breakpoint in the debugger?). That's how I found the race in ScrollerVBTClass.m3.
On 28 Sep 2009, at 09:11, Jay K wrote:
So, I know that ThreadWin32.T instances are prone to being overwritten.
So I did this:
T = BRANDED "Thread.T Win32-1.0" OBJECT
> pad1: ARRAY [0..16_1000] OF CHAR;
> protect: ARRAY [0..16_1] OF CHAR;
> pad2: ARRAY [0..16_1000] OF CHAR;
And then there are two occurences of NEW(T):
next_self := NEW(T);
> Protect(next_self);
PROCEDURE CreateT (act: Activation): T =
(* LL = 0, because allocating a traced reference may cause
the allocator to start a collection which will call "SuspendOthers"
which will try to acquire "activeMu". *)
VAR t := NEW(T, act := act);
BEGIN
> Protect(t);
PROCEDURE Protect(t: T)=
VAR old: WinDef.DWORD;
BEGIN
EVAL WinBase.VirtualProtect(LOOPHOLE(ADR(t.protect), SIZE_T), 1, PAGE_READONLY, ADR(old));
END Protect;
This should catch any writes to these fields.
Now, a thread can be garbage collected and reused.
And I'd want to unprotect this memory.
Or prevent the garbage collector from deciding any thread is garbage.
Second option seems easier and suffices.
So:
VAR
threads: ARRAY[0..2000] OF T; (* big enough for our purposes *)
threadCount: INTEGER;
and more completely:
PROCEDURE Protect(t: T)=
VAR old: WinDef.DWORD;
BEGIN
EVAL WinBase.VirtualProtect(LOOPHOLE(ADR(t.protect), SIZE_T), 1, PAGE_READONLY, ADR(old));
RTIO.PutInt(threadCount);
RTIO.PutText(" ");
RTIO.PutAddr(ADR(threads));
RTIO.PutText(" ");
RTIO.PutAddr(ADR(t.protect));
RTIO.PutText("\n");
threads[threadCount] := t;
INC(threadCount);
END Protect;
And just in case, I emptied out the FreeSlot function.
But yet I get:
0 0xe2abe0 0x1141021
1 0xe2abe0 0x114b429
2 0xe2abe0 0x11a2311
3 0xe2abe0 0x11a48b1
4 0xe2abe0 0x11ab499
5 0xe2abe0 0x12e9f11
6 0xe2abe0 0x12d211d
7 0xe2abe0 0x11bd691
8 0xe2abe0 0x11d1011
9 0xe2abe0 0x11d3e2d
10 0xe2abe0 0x11d6759
11 0xe2abe0 0x11d8bd1
12 0xe2abe0 0x12089f1
13 0xe2abe0 0x1211455
14 0xe2abe0 0x12138cd
15 0xe2abe0 0x1215ecd
16 0xe2abe0 0x12184cd
17 0xe2abe0 0x121bcd5
18 0xe2abe0 0x121e35d
Grow (0x210000) => 0x2120000 total: 4.1M span: 17.9M density: 23%
(b60.9d4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=011b0000 ebx=00010000 ecx=00000060 edx=00000000 esi=011b0000 edi=011bd000
eip=78545e37 esp=01cae5ec ebp=01cae5f0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206
MSVCR90!fastzero_I+0x20:
78545e37 660f7f07 movdqa xmmword ptr [edi],xmm0 ds:0023:011bd000=0000000
0000000000000000000000000
0:003> k
ChildEBP RetAddr
01cae5f0 78545ea9 MSVCR90!fastzero_I+0x20
01cae610 005dad48 MSVCR90!_VEC_memzero+0x36
01cae634 005d1f34 m3core!RTMisc__Zero+0x1f
01cae68c 005c8191 m3core!RTHeapRep__LongAlloc+0xf3
01cae6d8 005c7793 m3core!RTAllocator__AllocTraced+0xec
01cae70c 005c728d m3core!RTAllocator__GetTracedObj+0x8c
01cae730 005d07d9 m3core!RTHooks__AllocateTracedObj+0x15
01cae784 005d033f m3core!RTCollector__CollectSomeInStateZero+0x45e
01cae798 005cffd6 m3core!RTCollector__CollectSome+0x6e
01cae7dc 005c817c m3core!RTHeapRep__CollectEnough+0x9b
01cae81c 005c7d06 m3core!RTAllocator__AllocTraced+0xd7
01cae858 005c7348 m3core!RTAllocator__GetOpenArray+0x97
01cae880 00f9f50d m3core!RTHooks__AllocateOpenArray+0x19
01cae930 00f9f201 m3ui!WinScrnPixmap__PixmapFromRaw__ConvertColor+0x8f
01cae958 00f9e22f m3ui!WinScrnPixmap__PixmapFromRaw+0x71
01cae9ac 00eb4121 m3ui!WinScrnPixmap__Load+0x320
01caeee4 00eb298d m3vbtkit!Image__ScaleRaw+0xb30
01caef44 00fb2b72 m3vbtkit!Image__ApplyScaled1+0x166
01caef70 00fc0af8 m3ui!VBTRep__PixmapApply+0xbf
01caefcc 00fa6766 m3ui!Palette__ResolvePixmap+0x7db
0:003> r edi
edi=011bd000
0:003>
What am I confused about?
Why does it seem that even if I store some pointers in globals, they are getting garbage collected and reused?
I should debug BuildGlobalMap??
- Jay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090929/79d43962/attachment-0002.html>
More information about the M3devel
mailing list