News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

.WHILE lockup

Started by redskull, July 09, 2006, 02:48:11 AM

Previous topic - Next topic

redskull

my latest experiment is crashing wicked hard, for reasons still unkown, but not in the usual "program.exe has created an error etc etc" way.  This time, the computer locks up for the better part of a 60-90 seconds, and I mean locks up....no mouse, no screen updates, no hour-glass, no HD access, everthing is frozen for about a minute.  But the damnedest thing is that it continues on, right as rain, after the 'wait period'.  I narrowed it down to this code loop, through 'comment elemination':

mov ebx, 0
.WHILE ebx < 011h
  inc ebx
.ENDW

which generates this dissasembly:
004015e8 bb00000000        mov    ebx,0x0
004015ed eb01                  jmp      004015f0
004015ef 43                       inc      ebx
004015f0 83fb11                cmp     ebx,0x11
004015f3 72fa                    jb       004015ef

It all seemed good to me, but then the plot thickens.  I open it up in the debugger, try setting some breakpoints to isolate it, and find myself unable to.  It doesn't matter where I bother to set them; before, after, nowhere near the offending code, the program still locks up.  So I try stepping through it, from beggining to end, and nothing happens, it doesn't lockup at all! :(
I'm about to my wits end with this: I can't seem to isolate the problem in WinDBG, and the only way to get the .EXE to run right is to comment out a WHILE block that seems to work fine.  And on top of that, it never officially 'crashes', it just freezes for a really long time.  Honestly, i've never seen a computer 'freeze' so abruptly, and then come back completly unaffected.  Has anyone seen these symptoms before, and possibly reccommend a direction to look in?  Most of the other code is bitmap stuff, DC's and the like, if it helps.
alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

Ratch

redskull,

     I tried your code snippet by itself and it worked fine.  I suspect that the register EBX you are using is not being returned to the operating system with its old value intact like it should be.  Try a "scratch" register for your loop like EAX, ECX, EDX, and see if that solves it.  Otherwise, strip everything out of your program and send us the minimum program that locks.  Ratch

dsouza123

redskull

  If the code is in a proc what about having uses ebx ecx edx esi edi.

  It seems like instead of doing the loop 17 times it is doing about 4 billion times,
which can lock up the PC because no messages can get done, if this is is in your
only thread or the code is in the WinMain or WndProc.
  I've had it happen in test programs that do billions of calculations in a tight loop
without message processing, as soon as the loop ends the computer responds again.
  If there is a worker thread to do the calculation intensive routines there is no effect
on system responsiveness.

hutch--

Red,

Give this a try.


push ebx
mov ebx, 0
.WHILE ebx < 011h
  inc ebx
.ENDW
pop ebx
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

redskull

I tried these four alterations: swapping the loop counter to eax, ecx, edx, and using PUSH/POP to save the state, with the following baffeling consequences: using eax had no change, using ecx made it freeze for only about half the time (10-15 seconds), and using both edx and PUSH/POP made it work...ONCE :'(.  It assembled fine, ran perfectly, and quit normally, but when I tried to run it a second time (with no re-assemble), it went right back to the old way.  WTF?  I'm trying to find different section of code to isolate to see what effect it has, but 90% of the time it seems to be random; sometimes it works, sometimes it doesnt, and if it does work it rarely works more than once.  The only consistent factor that makes it work every time is removing the WHILE Loop that seems to be otherwise fine.  Seriously, i don't even know what *kind* of error this would be.  Memory accesses would kill the program, infinite loops usually just give me a moveable hour-glass mouse while other processes still run; i've never seen a program that will randomly freeze the entire PC.  Any and all suggestions will be appreciated, i'm at the end of my rope on this one.

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dsouza123

What about using a global variable instead of a register ?

How about using a repeat loop instead, and base ten constants ?


  mov abc, 0
  .while abc < 17
    inc abc
  .endw

  mov abc, 0   ; abc dd 0
  .repeat
     inc abc
  .until abc >= 17

  xor ebx, ebx
  .repeat
     inc ebx
  .until ebx >= 17

Ratch

redskull ,

     It's time for you to try the mimimalist method.  Take out everything that you can.  Stub off every subroutine call you can.  Then present the minimal program that hangs up to the Ineffable All for us to look at.  Ratch

redskull

well, problem fixed, but not really solved.  Much earlier in the program, there was a call to the API Polygon function, and after a *long* day of commenting things, that statement seems to be the culprit.  Apparently you can't count on it preserving the registers for you (whoops) :red.  Of course, that still leaves the question of why the .WHILE loop would cause it to work/not work, and why it would randomly lock up the computer.  I was under the impression that in a preemptive multitasking O/S, no matter how ridiculous your program gets, it can't interfere with another programs execution, and i'm pretty sure i didn't accidently circumvent all the Windows 2000 security features.  If the Ineffable All has some guesses, i'm always thrilled to learn about the mysteries.  And if not, thanks again to everybody for taking care of my dumb ass, you guys rule  :thumbu

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dsouza123

redskull

A program with a single thread in a tight loop doing calculations, running for a while
without any message handling and set to a very high priority, can freeze up a PC
until the program ends or exits the loop.

If you run out of physical memory and virtual memory is running off the disk and
the CPU gets too hot (summer time) and throttles all the way down,
it will seem like a freeze up.

tenkey

I remember some timing quirks related to loops.

In some cases, you could speed up a loop by lengthening it. I don't know why that is (register stall?), and couldn't tell you if this was a P4 quirk or not.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

redskull

So I think I may have come across the root of the problem (but at this point, nothing is certain).  I was looking over the declarations for the Polygon API function, and noticed something perculiar:

HDC  hdc,                                   // handle of device context
CONST POINT  *lpPoints,   // address of polygon's vertices
int  nCount                    // count of polygon's vertices

I had just thrown my polygon verticies in the .DATA section without giving it a second thought, but this caught my eye, and upon switching it to a .CONST section, things (seem) to work.  I know assembly language gets a little more leeway on the 'official' declarations (ie DWORD instead of HDC), but I guess when it says CONST, it means it?  Can anybody explain why an API function would *require* data to be read-only?  Does a problem like this seem consistint with the symptoms (random freezing, then continuing without a hitch?).  Thanks again for all the help

alan
Strange women, lying in ponds, distributing swords, is no basis for a system of government

sluggy

Quote from: redskull on July 14, 2006, 12:19:15 AMI know assembly language gets a little more leeway on the 'official' declarations (ie DWORD instead of HDC), but I guess when it says CONST, it means it?  Can anybody explain why an API function would *require* data to be read-only?  Does a problem like this seem consistint with the symptoms (random freezing, then continuing without a hitch?).  Thanks again for all the help

alan
APIs do not require that the data they access be read only, but memory access can be finicky if your data is not aligned on dword boundaries (especially structs).

Asm doesn't get more "leeway" over other languages. Data types are a product of the language and are consumed by the compiler, they have no effect on the output of the compiler (except the compiler will have no output if you et your types wrong) (and i hope that statement isn't too confusing). A DWORD and a HDC are synonymous - they are both the same size, and under the hood they are the same thing - just a pointer or an identifier.

What i am saying with all this is that these are not your problems. Your code looks fine, the only thing i would do with the .WHILE is change it to a signed compare. To me it is obvious: the problem is not in the code you have given us, it is either in another piece of code, or you haven't given us the full contents of the loop. If the bug was in the Polygon function, then it simply will not affect the loop, because you are explicitly setting the register that is being incremented before you enter the loop.

The problem could absolutely be the fact that your registers were not preserved upon return from the API, i have been caught out with this kind of bug many times. The rule you should follow is that you push or preserve any critical register before calling an API function, regardless of what the doco says. Also, your problem could be symptomatic of you accidentally overwriting your own stack, and code execution jumping to an unexpected location in the app.

I hope this little ramble helps somewhat  :P