Mail Archives: djgpp-workers/1999/05/02/07:28:07
A couple of months ago I wrote here about a strange problem with
signals in v2.02 (those who want to see the discussion should search
the mail-archives for a thread with a subject "Exceptions in v2.02"
circa January 1999).
As a simple example, the test program attached below, when compiled
with v2.02 and aborted with Ctrl-BREAK, prints registers that clearly
show that SS:ESP are on the exception stack (and the traceback EIPs
are therefore not printed). The same program compiled with v2.01
behaves normally, i.e. the full traceback is printed and SS:ESP are on
the normal application stack.
This weekend I finally found the cause of the different behavior.
(The reason it took such a long time was that using the old versions
for the ``usual suspects'', like dpmiexcp.c, exceptn.S and the startup
code, didn't affect the program behavior; so I actually needed to
replace the library modules one by one to find the offending one...)
The function that causes this problem is __dpmi_int (d0300_z.S in the
library). I attach below its full code, with the added lines marked
with ";+++" and the changed line marked as ";!!!".
Can somebody please tell what was the reason for this change in
__dpmi_int? (I cannot find anything pertaining to it in the v2.02
changes' description inside wc202.txi.)
If this change does have a good reason, perhaps other parts of the
library need to be changed as well? For example, exceptn.S switches
to the locked exception stack if DS != SS; perhaps now it should also
accept the DS alias?
Btw, I'm not sure I understand fully why does this change cause a wrong
SS to be in effect when the traceback is printed. So if somebody can
explain that, please do.
I believe that in more complex programs this change causes some grave
bugs, like GPFs in signal handlers when several different signals are
caught, etc. So I think we need to correct this ASAP.
Here's a test program to demonstrate the phenomenon. While it runs,
press Ctrl-BREAK twice to get the traceback.
-------------------------- cut here -------------------------------
#include <signal.h>
#include <stdio.h>
char **__crt0_glob_function (char *arg) { return 0; }
void __crt0_load_environment_file (char *progname) { }
void __crt0_setup_arguments (void) { }
void quit(int sig)
{
signal (SIGINT, SIG_DFL);
while (1)
puts ("in handler");
}
int main (void)
{
signal (SIGINT, quit);
while (1)
puts ("in main");
return 0;
}
--------------------------------------------------------------------
Here's the current source of __dpmi_int:
/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#define USE_EBX
#define USE_EDI
#include "dpmidefs.h"
.comm ___dpmi_int_ss, 2
.comm ___dpmi_int_sp, 2
.comm ___dpmi_int_flags, 2
.lcomm dpmi_busy, 1
.text
FUNC(___dpmi_int)
ENTER
pushl %es
pushl %ss ;+++ Line added
movw ___djgpp_ds_alias, %ax
movw %ax, %es
movw %ax, %ss ;+++ Line added
movl ARG1, %ebx
movl $0, %ecx
movl ARG2, %edi
incb dpmi_busy
cmpb $1, dpmi_busy
jne L_is_busy
movw ___dpmi_int_flags, %ax
movw %ax, 0x20(%edi) /* r.x.flags */
movw ___dpmi_int_sp, %ax
movw %ax, 0x2e(%edi) /* r.x.sp */
movw ___dpmi_int_ss, %ax
movw %ax, 0x30(%edi) /* r.x.ss */
jmp L_not_busy
L_is_busy:
movw $0, 0x20(%edi) /* r.x.flags */
movw $0, 0x2e(%edi) /* r.x.sp */
movw $0, 0x30(%edi) /* r.x.ss */
L_not_busy:
DPMI(0x0300)
xorl %eax,%eax
LEAVEP(decb dpmi_busy; popl %ss; popl %es) ;!!! "popl %ss;" added
- Raw text -