delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/04/10/13:55:07

From: "OiSyN" <oisyn AT afmp DOT nl>
Newsgroups: comp.os.msdos.djgpp
Subject: Processor Exceptions
Date: Mon, 10 Apr 2000 19:11:29 +0200
Message-ID: <955386420.5260.0.pluto.d4ee0fa5@news.demon.nl>
NNTP-Posting-Host: x-project.demon.nl
X-NNTP-Posting-Host: x-project.demon.nl:212.238.15.165
X-Trace: news.demon.nl 955386420 pluto:5260 NO-IDENT x-project.demon.nl:212.238.15.165
X-Complaints-To: abuse AT nl DOT demon DOT net
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 5.00.2615.200
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2615.200
Lines: 68
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp
Reply-To: djgpp AT delorie DOT com

Hi!

I was writing a thread-library for DJGPP to make it multi-threading.
I first used setitimer () to generate a SIGREAL, and I used a signal handler
to switch between threads. It worked fine, but a bit unstable, so I took a
look
at the DJGPP standard library (exceptn.S and dpmiexcp.c) how the timer
worked. I saw that whenever the timer countdown had reached zero, the ds
limit whas set to 0, which would generate an exception when your code reads
or writes. With an exception handler you can switch to another piece of
code,
in contrast with a normal iterrupt handler where you can't return to an
other address,
because the DPMI host doesn't allow that.

So I decided to write my own timer and exception handler.
The timer sets the length of __djgpp_app_DS to zero (the normal data
selector),
which will generate an exception as soon as you read/write a variable.
The exception handler (exception 0x0D) checks if the exception was generated
because of the timer interrupt, if it wasn't, it calls the old exception
handler.
If it was, it saves the registers to a buffer, sets the length of
__djgpp_app_DS to
whatever it was, changes the address of the instruction that generated the
exception
into my thread_switch_handler and returns with a retf.

It all worked fine (with only 1 thread) until I found out that my
thread_switch_handler
never got called. And I just don't understand why...

Whenever an exception handler is called, the stack is as follows:
[esp]            return eip (dword)
[esp+4]        return cs (word)
[esp+8]        error code (dword)
[esp+12]      eip of exception (dword)
[esp+16]      cs of exception (word)
[esp+20]      flags
[esp+24]      esp
[esp+28]      ss

So I changed the cs:eip of the exception into my thread_switch_handler, but
it isn't
called. The code of DJGPP is just like that, but that one works (obviously)

By the way, when my exception handler was called, and I returned from main
(after
restoring the old exception handler) or used an exit somewhere in my code, I
get an
error message from windows (not even the stack trace from DJGPP) which says
I have
to shut down all programs, reboot, and try again (yeah, like I'd really do
that. I just press
OK and everything works fine, but anyway...) The only way to get around this
error is
to set a signal handler for SIGSEGV, whichs calls exit, and then do
something like this:
    *(char *)-1L = 1;

Can someone point out to me what I'm doing wrong?
Just a detailed document about processor exceptions would be great to!
Thanx!

OiSyN
oisyn AT afmp DOT nl


- Raw text -


  webmaster     delorie software   privacy  
  Copyright 2019   by DJ Delorie     Updated Jul 2019