Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

help sought, possible asm/cpu/other problem???

1 view
Skip to first unread message

dhoke

unread,
Jul 16, 2008, 4:42:06 PM7/16/08
to
(Thanks in advance... Sorry if this seems off-topic to some, but it really
didn't seem non-technical in nature.)

1)Please report if you spot an error in the BytesOK() routine. Its intended
purposes is to scan the nbytes bytes starting at location pAddr, verifying
that all of those bytes have value bval. It does not explicitly clear
direction flag, but CPU pane reports direction flag as clear (see further
below.) If it finds a non-conforming byte, it may generate an int3, and
will return 1.
2)If the code does not have errors to cause functioning as other than
specified, any reasonable guesses as to why it would trip, with the
information in the CPU pane indicating it should not have indicated an
error?
3)All observed paths leading to this routine are protected by a
synchronization object (it could be reached from differing threads
otherwise)
4)It's only been in the last few weeks that I've started to encounter this,
but this code is part of a replacement heap manager, and is not always
active, although it ususally is on my development machine (for the better
part of the past year.)
5)The CPU disassembly pane does seem to correctly reflect the source written
(if(_eax &0x4000) optimized to test ah, $40.)

When this trip occurs (periodically), on two occasions, chasing the stack by
hand, I have found this in the stack as a seeming starting point (to freeing
some memory):
vcl100.@Graphics@TBrush@$bdtr$qqrv:
52006AD0 53 push ebx
(I've only walked the stack by hand twice, so far...)

int BytesOK(unsigned char *pAddr, unsigned char bval, unsigned nbytes)
{
unsigned ui ;
_asm
{
cld
mov al, bval
//apparently ecx is incremented whether or not compare eq or not...
//so our test for non-zero ecx fails.
mov ecx, nbytes
//We'll increment count of bytes, by one (1) - if actual filler
compares
//NE, ecx will be non-zero. If only the extra byte doesn't
compare, then
//ecx should still be zero. ***ASSUMPTION: There will always be at
//least one readable byte beyond any block...
//Probably bad, better find out where zero flag is and test that...
//inc ecx
mov edi, pAddr
repe scasb
lahf
//now, which bit is the zero/equal bit?
} ;
//if(_ECX)
if(!(_EAX & 0x4000)) //0x40 set in AH
{
if(!MM3AdminData.survivalmode)
if(MM3AdminData.callint3onerror) __asm int 3 ;
return 1 ;
}
return 0 ;
}


Mysteriously, BytesOK() routine trips calling int 3, with presented evidence
indicating to me it had no reason to do so. What might be happening?

pAddr == 0x044003e0
bval == 0xff
nbytes == 32

survivalmode == 0
callint3onerror == 1

cpu window shows ...
dump pane all bytes from 0x044003E0 through 0x044003FF as byte value 0xff
(as desired expected)
ZF == 0 (although would have been blown away by two comparisons after the
test ah, $40)
DF == 0
AL == 0xff
ECX == 0x7
EDI == 0x044003F9

code is protected by synchronization object at higher level,
(AsFarAsICanSee) for all paths leading to this point...

XP SP2, intel P4 3.6GHz hyper-threaded
(ACPI\GENUINEINTEL_-_X86_FAMILY_15_MODEL_4\_0) (computer box about 2.5
years old)

Remy Lebeau (TeamB)

unread,
Jul 16, 2008, 6:00:41 PM7/16/08
to

"dhoke" <dhoke....@east-shore.com> wrote in message
news:487e5d3c$1...@newsgroups.borland.com...

> (Thanks in advance... Sorry if this seems off-topic to some, but it
> really didn't seem non-technical in nature.)

This is not a Win32 API issue. This question would have been better
directed to the .language newsgroups instead.

> Please report if you spot an error in the BytesOK() routine.

Why use assembly for that? A simple loop would be easier to manage:

int BytesOK(unsigned char *pAddr, unsigned char bval, unsigned nbytes)
{

for(unsigned ui = 0; i < nbytes; ++i)
{
if( pAddr[ui] != bval )
{
if( !MM3AdminData.survivalmode )
{
if( MM3AdminData.callint3onerror )
__asm int 3 ;
else
return 0;
}
break;
}
}
return 1;
}


Gambit


Dennis Cote

unread,
Jul 16, 2008, 7:19:00 PM7/16/08
to
dhoke wrote:
>
> 1)Please report if you spot an error in the BytesOK() routine.

> 5)The CPU disassembly pane does seem to correctly reflect the source written

> (if(_eax &0x4000) optimized to test ah, $40.)
>

> lahf
> //now, which bit is the zero/equal bit?
> } ;
> //if(_ECX)
> if(!(_EAX & 0x4000)) //0x40 set in AH
> {

I think you are using the wrong constant. LAHF loads the 16 bit flags
register into AH. The zero flag is bit 6 in this register. To compare
using EAX the extended 32 bit register you need to shift your mask,
0x0040 left by 16 bits to give 0x00400000.

HTH
Dennis Cote

Bob Gonder

unread,
Jul 16, 2008, 8:15:33 PM7/16/08
to
Dennis Cote wrote:

>> lahf


>> if(!(_EAX & 0x4000)) //0x40 set in AH
>
>I think you are using the wrong constant. LAHF loads the 16 bit flags
>register into AH.

That would be hard to do as AH only has 8 bits.

> The zero flag is bit 6 in this register. To compare

Correct.

>using EAX the extended 32 bit register you need to shift your mask,
>0x0040 left by 16 bits to give 0x00400000.

Not correct.
AL is bits 0-7 of EAX.
AH is bits 8-15 of EAX ( 0x0100 to 0x8000 )
Bits 16-31 of EAX are not addressable.

The original code is correct for zf.
Though with all the assembly, it would
be clearer to continue with ASM.

mov edi, pAddr
repe scasb

je return0
};//end asm


if(!MM3AdminData.survivalmode)
if(MM3AdminData.callint3onerror) __asm int 3 ;
return 1 ;

return0:
return 0;


Bob Gonder

unread,
Jul 16, 2008, 8:43:09 PM7/16/08
to
Remy Lebeau (TeamB) wrote:

>Why use assembly for that? A simple loop would be easier to manage:

It is part of a memory manager, he wants it small and fast.

> int BytesOK(unsigned char *pAddr, unsigned char bval, unsigned nbytes)
> {
> for(unsigned ui = 0; i < nbytes; ++i)
> {
> if( pAddr[ui] != bval )
> {
> if( !MM3AdminData.survivalmode )
> {
> if( MM3AdminData.callint3onerror )
> __asm int 3 ;
> else
> return 0;
> }
> break;
> }
> }
> return 1;
> }

Your returns are backwards.
sb 1 for fail, 0 for ok.
if/else incorrect.


> int BytesOK(unsigned char *pAddr, unsigned char bval, unsigned nbytes)
> {
> for(unsigned ui = 0; i < nbytes; ++i)
> {
> if( pAddr[ui] != bval )
> {
> if( !MM3AdminData.survivalmode )
> {
> if( MM3AdminData.callint3onerror )
> __asm int 3 ;
> }

return 1;
> }
> }
> return 0;
> }


Bob Gonder

unread,
Jul 16, 2008, 8:48:33 PM7/16/08
to
dhoke wrote:

>(Thanks in advance... Sorry if this seems off-topic to some, but it really
>didn't seem non-technical in nature.)

Perhaps the TASM group?

>1)Please report if you spot an error in the BytesOK() routine. Its intended
>purposes is to scan the nbytes bytes starting at location pAddr, verifying
>that all of those bytes have value bval. It does not explicitly clear
>direction flag, but CPU pane reports direction flag as clear (see further
>below.)

Well, there's an error to start:
It Does clear the direction flag.

>int BytesOK(unsigned char *pAddr, unsigned char bval, unsigned nbytes)
>{
> unsigned ui ;

Warning: ui not used


> _asm
> {
> cld
> mov al, bval

> mov ecx, nbytes


> mov edi, pAddr
> repe scasb
> lahf
> //now, which bit is the zero/equal bit?
> } ;
> //if(_ECX)
> if(!(_EAX & 0x4000)) //0x40 set in AH
> {
> if(!MM3AdminData.survivalmode)
> if(MM3AdminData.callint3onerror) __asm int 3 ;
> return 1 ;
> }
> return 0 ;
>}

>pAddr == 0x044003e0
>bval == 0xff
>nbytes == 32

>dump pane all bytes from 0x044003E0 through 0x044003FF as byte value 0xff

I think you need to look a bit closer.

>ECX == 0x7

There were 7 bytes to go when it failed.

>EDI == 0x044003F9
>pAddr == 0x044003e0
0x00000019 = 25
pAddr[25] != bval
might be [24], forget exactly how repe handles edi.

dhoke

unread,
Jul 17, 2008, 8:31:39 AM7/17/08
to

"Remy Lebeau (TeamB)" <no....@no.spam.com> wrote in message
news:487e6fe0$1...@newsgroups.borland.com...

>
> "dhoke" <dhoke....@east-shore.com> wrote in message
> news:487e5d3c$1...@newsgroups.borland.com...
>
>> (Thanks in advance... Sorry if this seems off-topic to some, but it
>> really didn't seem non-technical in nature.)
>
> This is not a Win32 API issue. This question would have been better
> directed to the .language newsgroups instead.

OK, haven't taken note of that group.

>
> Why use assembly for that? A simple loop would be easier to manage:
>

The conditionally compiled version (removed from what I posted) was very
similar to what you've posted, and made the functionality using it in the
heap manager _painfully_ slow to use. The assembly version has made it
almost acceptable.


>
> Gambit
>


dhoke

unread,
Jul 17, 2008, 8:37:58 AM7/17/08
to

"Bob Gonder" <no...@nowhere.invalid> wrote in message
news:v25t74t1gkt8qe9ne...@4ax.com...

> Remy Lebeau (TeamB) wrote:
>
>>Why use assembly for that? A simple loop would be easier to manage:
>
> It is part of a memory manager, he wants it small and fast.

Correct. And the difference was significant, as I also have a version
similar to what Remy posted.

>
> Your returns are backwards.
> sb 1 for fail, 0 for ok.
> if/else incorrect.

Nope, they're what I want. Yes its "backwards" from C convention, but its
terribly convenient to be able to return multiple (non-zero) failures from a
routine, and have a clue as to what part of a routine failed. In this
particular routine, not significant, but its a convention I have in my code.
Just think "shell" programming (not that I've done much of that), or I
suppose even batch/command file is similar...

dhoke

unread,
Jul 17, 2008, 8:53:06 AM7/17/08
to
Didn't follow your train of thought, comments below...

"Bob Gonder" <no...@nowhere.invalid> wrote in message

news:op3t7457p6inr75u4...@4ax.com...


> dhoke wrote:
>
>>that all of those bytes have value bval. It does not explicitly clear
>>direction flag, but CPU pane reports direction flag as clear (see further
>>below.)
>
> Well, there's an error to start:
> It Does clear the direction flag.

Which I wanted as that should cause EDI to be incremented, and looked for
when I was searching for possible cause/error, but for some reason
overlooked (I think I was looking in disassembly pane rather than source at
time I checked, somehow missed fact that I had included it.)

>
>>int BytesOK(unsigned char *pAddr, unsigned char bval, unsigned nbytes)
>>{
>> unsigned ui ;
> Warning: ui not used

yeah, that's for the conditionally compiled slower version I removed after
inserting in the email.


>> _asm
>> {
>> cld
>> mov al, bval
>> mov ecx, nbytes
>> mov edi, pAddr
>> repe scasb
>> lahf
>> //now, which bit is the zero/equal bit?
>> } ;
>> //if(_ECX)
>> if(!(_EAX & 0x4000)) //0x40 set in AH
>> {
>> if(!MM3AdminData.survivalmode)
>> if(MM3AdminData.callint3onerror) __asm int 3 ;
>> return 1 ;
>> }
>> return 0 ;
>>}
>>pAddr == 0x044003e0
>>bval == 0xff
>>nbytes == 32
>>dump pane all bytes from 0x044003E0 through 0x044003FF as byte value 0xff
>
> I think you need to look a bit closer.
>
>>ECX == 0x7

>
> There were 7 bytes to go when it failed.


Yes - and the following 7 bytes were all bval (0xff)... as well as the
preceding 25 or so...

>
>>EDI == 0x044003F9
>>pAddr == 0x044003e0
> 0x00000019 = 25
> pAddr[25] != bval
> might be [24], forget exactly how repe handles edi.
>

((char*)pVal + 25) == 0x44003f9
*((char*)pVal + 25) == 0xff (all 32 bytes from 0x44003e0 through 0x44003ff,
which includes 0x44003f9)

I'm not following your train of thought, as pVal[24] and pVal[25] as well as
preceding and following bytes were all bval...

(I think) The routine should _not_ have tripped, calling the int 3, but it
did - even though the circumstances presented by the debugger indicate to me
it should not have...

>
>


dhoke

unread,
Jul 17, 2008, 9:47:19 AM7/17/08
to
Wonder what, if any bearing this could have. I am not running in 64-bit
mode, but my PC was manufactured before December 2005, and the processor
does have EM64T...

from:
http://jetteroheller.wordpress.com/2007/03/09/whats-the-difference-between-amd64-and-intel-em64t/

"Early Intel CPUs with EM64T lacked LAHF and SAHF instructions supported by
AMD64 until introduction of Pentium 4 G1
step in December 2005. LAHF and SAHF are load and store instructions,
respectively, for certain status flags. These instructions are used for
virtualization and floating-point condition handling."

I do have to wonder if the blurb is referring to the correct instructions???

"dhoke" <dhoke....@east-shore.com> wrote in message
news:487e5d3c$1...@newsgroups.borland.com...

> _asm
> {
> lahf
> } ;

p.s. There is a borland.public.cppbuilder.language.basm group, which I will
try to remember for future use.


Dennis Cote

unread,
Jul 17, 2008, 10:11:39 AM7/17/08
to
Bob Gonder wrote:
>
> That would be hard to do as AH only has 8 bits.
> AL is bits 0-7 of EAX.
> AH is bits 8-15 of EAX ( 0x0100 to 0x8000 )

You are correct. My memory must have failed me. I assumed that LAHF
loaded the entire flags register, but it only loads the low byte of the
flags register.

>
> The original code is correct for zf.
> Though with all the assembly, it would
> be clearer to continue with ASM.
>
> mov edi, pAddr
> repe scasb
> je return0

That is true as well.

The only other thing I can think of is that the ES register (used
implicitly by the SCAS instructions) may have a different value than the
DS register for some reason, thus EDI (i.e. pAddr) is not pointing at
the expected memory when the SCAS is executed.

Dennis Cote

Bob Gonder

unread,
Jul 17, 2008, 4:24:18 PM7/17/08
to
Larry Griffiths wrote:

>> mov edi, pAddr
>
> repe scasb // I do not think this is checking that ALL the
>characters are equal to what is in register al.

Why?
What do you think it does that isn't intended?


Bob Gonder

unread,
Jul 17, 2008, 4:17:24 PM7/17/08
to
dhoke wrote:

>I do have to wonder if the blurb is referring to the correct instructions???

Well, as I posted earlier, it is blindingly easy to replace the lahf with a je

>p.s. There is a borland.public.cppbuilder.language.basm group, which I will
>try to remember for future use.

Also b.p.TASM
And if you are looking for fast code,
the fastcode project posts asm in the delphi.basm group.
There I think you will find that repe scasb is slow.

Larry Griffiths

unread,
Jul 17, 2008, 4:17:24 PM7/17/08
to

"dhoke" <dhoke....@east-shore.com> wrote in message
news:487e5d3c$1...@newsgroups.borland.com...

repe scasb // I do not think this is checking that ALL the

characters are equal to what is in register al.

Larry


Larry Griffiths

unread,
Jul 17, 2008, 7:30:04 PM7/17/08
to
I guess I should type in the code and anaylze it. I have not done any
assembler coding in years.

I think I know what he wants though.

I will post back later.

Larry.


"Bob Gonder" <no...@nowhere.invalid> wrote in message

news:5eav74prnv13lrm6g...@4ax.com...

Larry Griffiths

unread,
Jul 17, 2008, 8:14:20 PM7/17/08
to
Look at this and see if it is close to what you want.


##########################################

bool BytesOK( unsigned char *pAddr, unsigned char bval, unsigned nbytes )
{
if( nbytes )
{
_asm
{
cld
mov al, bval // Value to compare
mov ecx, nbytes // Number of bytes to compare
mov edi, pAddr // Address of buffer
repe scasb
jz ItsOK:
}
//if(!MM3AdminData.survivalmode)
// if(MM3AdminData.callint3onerror) __asm int 3 ;
return 0 ;
}
ItsOK:
return 1 ;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ASMButtonClick(TObject *Sender)
{
long BytesOKCount = 0;
long BytesNotOKCount = 0;

unsigned char* Buffer[257] = { "AAB" };

for( int a = 1; a < 10; a++ )
{
if( BytesOK( Buffer[0], 'A', a ) )
{
BytesOKCount++;
}
else
{
BytesNotOKCount++;
}
}
}

##########################################

Larry Griffiths

"dhoke" <dhoke....@east-shore.com> wrote in message
news:487e5d3c$1...@newsgroups.borland.com...

Larry Griffiths

unread,
Jul 17, 2008, 8:52:59 PM7/17/08
to
If your character arrays are very large then more code might be added to
compare dwords, words and then bytes.

Larry Griffiths


Larry Griffiths

unread,
Jul 17, 2008, 8:49:22 PM7/17/08
to
I think I like this better...

#########################################################

bool BytesOK( unsigned char *pAddr, unsigned char bval, unsigned nbytes )
{
_asm
{


mov ecx, nbytes // Number of bytes to compare

jz ItsOK:


cld
mov al, bval // Value to compare

mov edi, pAddr // Address of buffer
repe scasb
jz ItsOK:
}

//if(!MM3AdminData.survivalmode)
// if(MM3AdminData.callint3onerror) __asm int 3 ;

return 0 ;

ItsOK:

return 1 ;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ASMButtonClick(TObject *Sender)
{
long BytesOKCount = 0;
long BytesNotOKCount = 0;

unsigned char* Buffer[257] = { "BAAB" };

for( int a = 0; a < 5; a++ )
{
if( BytesOK( Buffer[0] + a, 'A', a ) )
{
BytesOKCount++;
}
else
{
BytesNotOKCount++;
}
}
}

#########################################################

Larry Griffiths


Bob Gonder

unread,
Jul 17, 2008, 11:02:31 PM7/17/08
to
Larry Griffiths wrote:

>Look at this and see if it is close to what you want.

Three to four times faster (tested):

#pragma argsused
__declspec(naked)
BOOL __fastcall BytesOKBob( unsigned char *pAddr, unsigned char bval, unsigned nbytes )
{ // eax = pAddr edx = bval ecx = nbytes
asm{
mov dh,dl
sub ecx,4
jc short loop2
push edx // mul edx, 0x00010001
mov word ptr [esp+2],dx
pop edx
}
loop4:
asm{
cmp [eax],edx
jne short fail
add eax,4
sub ecx,4
jnc loop4
}
loop2:
asm{
add ecx,2
js short loop1
cmp [eax],dx
jne short fail
add eax,2
sub ecx,2
}
loop1:
asm{
add ecx,1
js short pass
cmp [eax],dl
jne short fail
}
pass:
asm{
xor eax,eax ;// return 0
ret
}
fail:
asm{
cmp [survivalmode],0
jne short noint
cmp [callint3onerror],0
je short noint
int 3
}
noint:
asm{
mov eax,1 ;// return 1
ret
}
return 1; // compiler prefers to see a C return.
// but there is a no-stack bug that doesn't generate the ret.

dhoke

unread,
Jul 18, 2008, 3:12:02 AM7/18/08
to

"Bob Gonder" <no...@nowhere.invalid> wrote in message
news:mg9v74tvanottpsga...@4ax.com...

> dhoke wrote:
>
>>I do have to wonder if the blurb is referring to the correct
>>instructions???
>
> Well, as I posted earlier, it is blindingly easy to replace the lahf with
> a je

I added that, and still left the lahf - it still "bogus" trips,
interestingly, so far with the bogus ones (there are legit ones) always in a
particular address region, with varying # of filler bytes, and with
remaining bytes to check 7 (cx == 0x7)

more on this in another post.

>
>>p.s. There is a borland.public.cppbuilder.language.basm group, which I
>>will
>>try to remember for future use.
>
> Also b.p.TASM
> And if you are looking for fast code,
> the fastcode project posts asm in the delphi.basm group.
> There I think you will find that repe scasb is slow.
>

Still faster than the straight-forward c version, but I suppose I could get
fancier - I vaguely remember the optimizations seen in ms memcpy version
(think thats where I saw movsd, except for leading/trailing bytes.)
Currently not worth the effort for me.


dhoke

unread,
Jul 18, 2008, 3:15:38 AM7/18/08
to
Well, since you've gone to the trouble, maybe the other isn't fast enough
anymore... :)

"Bob Gonder" <no...@nowhere.invalid> wrote in message

news:8bqv74t64fcgrl6la...@4ax.com...

dhoke

unread,
Jul 18, 2008, 3:34:55 AM7/18/08
to
This issue is partially resolved. It's apparently a bds2006 debugger issue.

Using a hacked program to externally read the debuggee process memory after
a bogus trip (in the filler region being checked by bytesOK) shows that, in
fact, the byte at that particular location is _NOT_ what the debugger is
displaying in the CPU pane. The debugger is displaying 0xff for location
0x04403f8. The hack program shows the byte as 0xcc (and all the other bytes
in the filler region as 0xff, as does the debugger. hackprog also agrees
about 4-bytes preceding and following the filler area [so I think the hack
is probably working correctly]. It seems to differ only in the one byte
currently of interest.)

The bds2006 debugger cpu window memory dump display is apparently incorrect.

So what if I can't trust the tools (not that I have anyway for a while) - I
got Bob G to write me some nifty faster code - maybe it'll balance out if I
can manage that a few more times. :) (Well, would need it a LOT more
times...)

And I guess I can assume my CPU isn't actually failing in this regard - that
at least is good.


dhoke

unread,
Jul 18, 2008, 5:17:32 AM7/18/08
to
And it just occurred to me that 0xcc is an int 3 instruction...

And further occurred to me to check my breakpoints. Sure enough, I have an
address breakpoint set with that value (two of them it seems.)

So I guess it's my fault after all, not bds2006.

"dhoke" <dhoke....@east-shore.com> wrote in message

news:488047c1$1...@newsgroups.borland.com...

dhoke

unread,
Jul 18, 2008, 5:49:45 AM7/18/08
to
After even further thought, I'm a little surprised that the debugger
wouldn't have removed that breakpoint when it stopped, thus causing memory
to match what it was displaying as what should be there, although, at the
same time, I'm happy it didn't, because if it did I wouldn't have been able
to read it with the external program and (eventually) see what was happening
to me... So that, I suppose, might still be considered an IDE/debugger bug,
as its left a process image in a state other than what it displays, but I
suppose that can be considered the prerogative of the debugger, and maybe
even, at least in this case, a good thing.

Perhaps it treats the traps of coded int 3's differently from the
breakpoints it sets, in this regard (or not - but right now I don't feel
like trying to figure that out.)

"dhoke" <dhoke....@east-shore.com> wrote in message

news:48805fcf$1...@newsgroups.borland.com...

Alan Bellingham

unread,
Jul 18, 2008, 7:13:16 AM7/18/08
to
"dhoke" <dhoke....@east-shore.com> wrote:

>Perhaps it treats the traps of coded int 3's differently from the
>breakpoints it sets, in this regard (or not - but right now I don't feel
>like trying to figure that out.)

I know little about the internal operation of debuggers, but if it sets
a breakpoint, it may be replacing the instruction that was at the
breakpoint position with the 'int 3'. It knows that it's done so, and
when it stops, it can replace the instruction with the original before
single-step executing it, and returning the 'int 3' afterwards.

On the other hand, an 'int 3' in your compiled code *was* the original
instruction. So no replacement was made, and the debugger *has* to treat
it differently. (For one, executing the *next* instruction next, rather
than the current (replaced) one.

Alan Bellingham
--
Team Browns
ACCU Conference 2009: to be announced

dhoke

unread,
Jul 18, 2008, 8:36:34 AM7/18/08
to
I now suspect/speculate (no verification attempted) its because I actually
had two address breakpoints set - It set up for one, and stored/saved actual
data - it set up for the second one, and stored/saved the replaced byte from
the previous one, an int 3 - So I can also speculate that it sets up for
breakpoints traversing the list in one direction, and "undoes" the
breakpoints in the same direction - whereas it might have "undone" them in
the reverse order of setting them, and actually gotten the original data
back in place. (In which case I'd still have no clue what was going on.)

This still does not explain how the display shows what should be there,
rather than what is apparently actually there. Maybe the display is
retrieving data via one thread, while the breakpoint management is done via
another thread, and the display just happens to fetch data after 'first'
breakpoint (with correct data) is restored, but before 'second' breakpoint
with incorrect data is 'restored' (overwriting actual data.)

(CGMWTTN - CodeGearMayWantToTakeNotice)
This may beg the additional question of what happens if I wanted to set two
breakpoints with two different conditions at the same address. The debugger
allows me to set the two breakpoints, but what will the reliability of its
interpretation of the expressions be, if the referenced data is not correct?


"Alan Bellingham" <al...@lspace.org> wrote in message
news:veu0849paoflcoovi...@4ax.com...

Larry Griffiths

unread,
Jul 18, 2008, 9:24:30 AM7/18/08
to
Nice job Bob!

:)

Larry Griffiths

"Bob Gonder" <no...@nowhere.invalid> wrote in message
news:8bqv74t64fcgrl6la...@4ax.com...

0 new messages