Date: Tue, 7 Jan 1997 10:45:36 +0100 (MET) From: Robert Hoehne To: Bill Currie Cc: "Salvador Eduardo Tropea (SET)" , djgpp-workers AT delorie DOT com Subject: Re: Debuggers and mouse hooking (or maybe dpmi memory allocatio In-Reply-To: <32D0E97E.2288@blackmagic.tait.co.nz> Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII On Mon, 6 Jan 1997, Bill Currie wrote: > The debugger's (in 2.01) don't preserve the flags register properly. > ALL of the return flags are set from within the isr (rather than just > the > carry flag). This also explains why it worked under windows: in > windows, > the isr is called with interrupts enabled but cwsdpmi calls the isr with > them disabled, and so the interrupts were being disabled! I think here is a misunderstanding of you (or me). The code in dbgcom.c restores (as you said correct) all and exactly the flags, which are returned by the original int 0x31. I don't know why this should be a problem. If there is a problem (in your program), then you will get it also when not running under a debugger, because in that case you get exactly these flags. > There was aslo some other problems with register preservation with some > of the > intercepted functions, so I fixed those whils I was at it. Really?? Please explain it more exactly, because I found nothing. ---------- And now to the patch: I'm not aggree with your patch for dbgcom.c. There are some bugs and things, I don't understand why you changed them. The first strange bug: >*** src/debug/common/dbgcom.c Tue Aug 13 00:08:04 1996 >--- new/debug/common/dbgcom.c Sun Dec 29 19:25:04 1996 >*************** >*** 331,337 **** > Lc31a_: pushl %eax \n\ > pushf \n\ > popl %eax /* store the right flags for iret */ \n\ >! movl %eax,12(%esp) \n\ > popl %eax \n\ > Lc31a: iret \n\ > Lc31b: .byte 0x2e \n\ >--- 325,332 ---- >Lc31a_: pushl %eax \n\ > pushf \n\ > popl %eax /* store the right flags for iret */ \n\ >! andl $1,%eax /* we only want the carry flag */ \n\ >! orl %eax,12(%esp) \n\ > popl %eax \n\ > Lc31a: iret \n\ > Lc31b: .byte 0x2e \n\ > Probably you think, that it had to do with the IF bit in the flags, but this is in my opinion not true. I have looked again in my 80386/80486 book, and there is said, that an IRET clears the IF bit. But now comes the very strange thing. If you look a little bit longer on your code, then you will see, that you only return the correct SETTING of the CF bit. Any other change is not recorded. To explain it I will give you an example #include #include int main() { int dummy_variable; asm("stc"); if (__dpmi_allocate_dos_memory(10,&dummy_variable) == -1) printf("failed\n"); else printf("success\n"); return 0; } will print "success" when running normal and "failed" when running under a debugger using your patch. BTW: I have build fsdb with your patched dbgcom.c and was unable to debug the above program, after the first F8 it exited with exit code 7. And now I found, why fsdb failed. Exactly because of the same like I wanted to show with the example. The startup code calls at first DPMI function 0x0507 (set page attributes) which is a DPMI 1.0 function and not supported when running under W95 (I'm running it there). So that call returns a CF=1 and the next call to int 0x31 returns then also CF=1 but the call was successfull. BTW: Is that correct, that we are calling a DPMI 1.0 function in the startup code without checking the DPMI version? And now I have tested it in raw MS-DOS and got the expected result of my sample program (print "failed" when running under the patched fsdb). Now to the other parts of your patch. The only thing which I aggree are the two first parts (the removing of the unneeded pushl/popl pairs). All the other changes do not change any existing functionality, but only change some code. Example: >*************** >*** 375,384 **** > .byte 0x2e \n\ > lcall _old_i31 \n\ > jc Lc31_resize_mem_error \n\ >! popl %eax \n\ > xorl %edx,%edx \n\ > call _change_handle \n\ >! xorl %eax,%eax \n\ > jmp Lc31a_ \n\ > Lc31_resize_mem: \n\ > pushw %si \n\ >--- 372,383 ---- > .byte 0x2e \n\ > lcall _old_i31 \n\ > jc Lc31_resize_mem_error \n\ >! xchgl %eax,(%esp) \n\ >! pushl %edx \n\ > xorl %edx,%edx \n\ > call _change_handle \n\ >! popl %edx \n\ >! popl %eax \n\ > jmp Lc31a_ \n\ > Lc31_resize_mem: \n\ > pushw %si \n\ Why this?? You are saving the contents of eax but it is not used because the success of the DPMI call is returned by CF=0 and in that case no return value in eax is expected. OH!! An now I see that there is also a bug. What is if _change_handle set CF=1?? In that case the DPMI call would return an error, but it is not an error. (It can set CF=1 if it is the 256th or higher handle, which is probably never true, but nobody knows) OK, may be I see all that from a wrong point, but I think, you should think again a little bit about your patch (You can believe me that I thought many many days about my changes, because it is very hard to debug that code) Robert ***************************************************************** * Robert Hoehne, Fakultaet fuer Mathematik, TU-Chemnitz-Zwickau * * Post: Am Berg 3, D-09573 Dittmannsdorf * * e-Mail: Robert DOT Hoehne AT Mathematik DOT TU-Chemnitz DOT DE * * WWW: http://www.tu-chemnitz.de/~rho * *****************************************************************