I am trying to port some more code from windows 2000 to linux. The
specific functionality I would like to port is called "Structured
Exception Handling" and it works like so:
1. Define a function which based upons a signal throws an exceptoion.
For example:
void translateException(unsigned int u, EXCEPTION_POINTERS* pExp)
{
switch (u)
{
case (unsigned int)0xc0000005:
throw AccessViolationException("SE_Exception::translateException() - u ==
0xc0000005", pExp, u);
break;
default:
throw SE_Exception("SE_Exception::translateException() - default:", pExp,
u );
}
}
The idea here is that the function translates the windows "signal" to a
user defined exception object.
2. call the Windows API function _set_se_translator(translateException).
3. when a OS trap -- like an access violation -- occurs the specified
function will be called.
4. From within the body of that function a user defined exception object
(MyAccessViolationException) can be thrown which can be caught anywhere in
the offending stack frame. e.g.
try
{
int* pNull = 0;
*pNull = 12;
}
catch (MyAccessViolationException& e)
{
printf ("success.\n");
}
Having researched the web, I have taken the followign approach: When I
receive a SIGSEGV signal, I need to insert the "exception throwing" function
into the stack frame which caused the exceptoion, return to it, and throw
out the exception from within it. In effect I need to insert a new function
to be exectued after the signal has been handled. This stack tampering
needs to be done because when I handle the signal I have no guarantee, and
in fact am not in the same stack frame I was in when the synchronous
exception arose. I know that messing with the stack is about as
non-portable as you can be, but oh well I'd rather have my code work on one
other platform besides Windows then none at all.
So in my quest to figure out how to do all this I stumbled upond a gnu
article on how to translate signals into Java exceptions. Based on that I
came up with the following code:
int i = 0;
//Signal handler function. The remmed out args reflect my attempt to make
this work with both POSIX.1 and POSIX.4
void on_accvio(int signo/*, siginfo_t *info, void *ignored*/)
{
printf ("[%d] - on_accvio() : entered %d\n", pthread_self(), i++);
void **_p = (void **)&signo;
throw true;
struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p;
register unsigned long _ebp = _regs->ebp;
register unsigned long _eip = _regs->eip;
asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)" : : "r"(_ebp),
"r"(_eip));
//These are remmed out because I was testing stuff.
// register unsigned long _esp = _regs->esp;
// asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp); mov %1, 4(%%esp)" : :
"r"(_ebp), "r"(_eip), "r"(_esp));
//I am throwing out the boolean just for now. Later it will be a real
exception object.
throw true;
}
struct sigaction sa;
void init_signal_machinery()
{
sigemptyset(&sa.sa_mask);
sa.sa_handler = on_accvio;
sa.sa_flags = 0;
if (sigaction(SIGSEGV, &sa, NULL))
{
printf("initlog() : sigaction() failed.\n");
exit(1);
}
return;
}
Anyways, this approach is close, but not exactly there. It modifies the
stack frame alright, and the thrown boolean is caught fine. However when I
return to the offending stack code, my stack is pretty much messed up; no
passed in arguments, including the implicit this pointer are correct.
However if I return out of that particular function everything is fine.
Anyways I need to know how to modify my stack memory pointer before
returning to the offending code.
Any help would be greatly appreciated, as assembly and I are on VERY formal
terms.
Thanks,
Tervel Atanassov
Why? Isn't that completely extraneous to just handling the signal via the
usual?
Rick Hohensee
www.clienux.com
: I am trying to port some more code from windows 2000 to linux. The
: specific functionality I would like to port is called "Structured
: Exception Handling" and it works like so:
: ...
You can have a look at the wine code how wine translates SEH
Bye
--
Uwe Bonnes b...@elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
Tervel
"cLIeNUX user" <r@cLIeNUX.> wrote in message
news:tkl9qfq...@corp.supernews.com...
What access violation? You have a signal. That's exceptional. You've
called the signal handler installer to install your signal handler
already. When the signal happens later, your handler is invoked. Now why
throw something else?
What stack are you going to unroll when you get a signal? For that to
matter you'd have to be all in one process, no?
Sorry to be answering questions with questions. I hope you get a better
answer.
Rick Hohensee
And there was me thinking the new standard did.
JAB.
--
Jonathan A. Buzzard Email: jona...@buzzard.org.uk
Northumberland, United Kingdom. Tel: +44(0)1661-832195
Q: Why can't you have sex in the middle of a shopping mall?
A: Because as soon as you start everyone will start giving you pointers and
their opinions, and nothing's ever going to happen.
I guess a similar answer goes for why can't you ever get useful information
from a newsgroup.
Do you actually know how C++ exceptions work? When an exception occurs, the
stack of functions that led up to the exception begins unrolling until a
proper handler is found.
> What stack are you going to unroll when you get a signal? For that to
> matter you'd have to be all in one process, no?
No shit, a process handles its own signals. Not those of other processes.
The stack is obviously that of the process which caused the exception.
Please spare me your diatribe and answer my assembly question please. If
you have no idea how to write the registers so it appears like the signal
handler got called from the place where the access violation happened, then
shut up!
Tervel
"cLIeNUX user" <r@cLIeNUX.> wrote in message
news:tkno5et...@corp.supernews.com...
Tervel
"Jonathan Buzzard" <jona...@happy.buzzard.org.uk> wrote in message
news:216hi9...@192.168.42.254...
I develop compilers (Modula-2, Ada95) and I trap certain system signals
(SIGSEGV, SIGBUS) and "raise" these as exceptions in the native language.
This is done with knowledge of how the language exception mechanism is
implemented. The signal is handled by using sigaction, after that it becomes
implementation dependent.
MS structured exception handling has no equivalent in "Unix". It is a
generic exception system built into the operating system. So for example my
M2 code could trap C/C++ exceptions as long as both compilers are using the
system exception mechanism underneath it all.
Unix has signals, which is basically a subset of the capability of exception
mechanisms. This is the source of your issues since without implementation
details you may not be able to "convert" a signal to an "exception".
--
Norman Black
Stony Brook Software
the reply, fubar => ix.netcom
"John Johnson" <jjoh...@hotmail.com> wrote in message
news:ZJw27.32680$QG2.1...@news1.bnapk1.occa.home.com...
> file://Signal handler function. The remmed out args reflect my attempt to
make
> this work with both POSIX.1 and POSIX.4
>
> void on_accvio(int signo/*, siginfo_t *info, void *ignored*/)
> {
> printf ("[%d] - on_accvio() : entered %d\n", pthread_self(), i++);
> void **_p = (void **)&signo;
> throw true;
>
> struct sigcontext_struct *_regs = (struct sigcontext_struct *)++_p;
> register unsigned long _ebp = _regs->ebp;
> register unsigned long _eip = _regs->eip;
> asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp)" : : "r"(_ebp),
> "r"(_eip));
> file://These are remmed out because I was testing stuff.
> // register unsigned long _esp = _regs->esp;
> // asm volatile ("mov %0, (%%ebp); mov %1, 4(%%ebp); mov %1, 4(%%esp)" : :
> "r"(_ebp), "r"(_eip), "r"(_esp));
> file://I am throwing out the boolean just for now. Later it will be a