Mail Archives: djgpp-workers/1997/01/07/04:53:02
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 <dpmi.h>
#include <stdio.h>
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 *
*****************************************************************
- Raw text -