[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [libunwind] Changing the value of "gp"
From: |
Praveen Vegulla |
Subject: |
Re: [libunwind] Changing the value of "gp" |
Date: |
Mon, 20 Jan 2003 10:17:19 -0800 (PST) |
Hi David,
Thanks for the quick reply.
There are a couple of reasons for doing the exception
handling this way. I've put the pseudo code below
for 2 cases. The high level description of the issue
is:
1. The reason for doing a setjmp() is, when there is
an exception, we do a longjmp(), and this will
get the execution to the "if ()" block of setjmp()
where I can do backout some changes.
This should be doable even without using setjmp(),
but it gets very tricky, when setting up multiple
exception handlers in the same function and also
when the callees themselves setup multiple
handlers.
2. The way we track exception handlers is thru an
exception stack. Each time an exception handler is
setup, we push the corresponding info onto the
exception stack. And the handler setup in a
function
should only be valid for this function and its
callees.
So, when a function returns, the exception handler
installed by that function should be popped of the
exception stack.
Case 1:
-------
#define SETUP_EXC(funcptr) setjmp(setup_exc(funcptr))
funcB()
{
.....
funcC();
.....
}
funcC()
{
...
if (SETUP_EXC(E1, E1_hdlr))
{
backout changes dones in this function;
And if reqd. re-raise another exception;
}
................
}
When there is an exception, we issue a longjmp()
making setjmp() return a non-zero value and we enter
the backout section.
Case 2:
-------
funcB()
{
....
if (SETUP_EXC(E1, E1_funcB_hdlr))
{
do ABC;
}
funcC();
...
if (something_bad_happened)
{
raise_exception(E1);
}
}
funcC()
{
...
if (SETUP_EXC(E1, E1_funcC_hdlr))
{
do XYZ;
}
}
The issue here is, an exception handler for E1 has
been pushed onto the stack by funcB(). After which
another handler for E1 has been pushed onto the stack
by funcC(). Now, if there is an exception E1 in
funcC(), it should be handled by E1_funcC_hdlr(). Lets
assume funcC() has returned, in funcB() when we raise
E1, we will check the exception stack to see who
should handle this. And here we mistakenly will pick
up E1_funcC_hdlr() - this is incorrect.
Please let me know if I wasn't clear.
Thank you,
Praveen
--- David Mosberger <address@hidden> wrote:
> Something seems very strange here. I don't think
> there should be any
> need for setjmp() at all.
>
> When raising an exception, why not just:
>
> - unwind until the IP is in funcB()
> - execute whatever "exception" handling you need to
> do
> - do an unw_resume() on the current cursor
>
> That would resume control in funcB().
>
> --david
>
> >>>>> On Fri, 17 Jan 2003 17:49:23 -0800 (PST),
> Praveen Vegulla <address@hidden> said:
>
> Praveen> Hi,
> Praveen> I'm an absolute newbie to Itanium and I
> apologize if
> Praveen> this is a very basic question. (Sorry
> about the length
> Praveen> of the mail.)
>
> Praveen> I'm trying to implement exception
> handling as follows:
>
> Praveen> Assuming the following call sequence:
> Praveen> funcA() -> funcB() -> funcC()
>
> Praveen> I need to install a exception handler in
> funcC(). I do
> Praveen> this by calling setjmp() in funcC() and
> using the
> Praveen> unwind library, I step up to funcB() and
> change the IP
> Praveen> to an exception cleanup function. At this
> point I save
> Praveen> the original IP for funcB() in a global.
> I had to do
> Praveen> it this way since there is no builtin (at
> least none
> Praveen> that I'm aware of) in gcc equivalent to
> _Asm_set_rp()
> Praveen> avaliable in the HPUX compiler suite.
>
> Praveen> The way it works is pretty simple, if I
> need to raise
> Praveen> an exception in funcC() or any of its
> callees, all I
> Praveen> need to do is issue a longjmp() to the
> location where
> Praveen> I setup the exception handler.
>
> Praveen> The tricky part is, if there was no
> excpetion, then I
> Praveen> need to cleanup the exception handler
> that I installed
> Praveen> and hence the reason for setting the
> return address (a
> Praveen> hack used by changing the IP in funcB()).
> So when
> Praveen> funcC() returns, it goes back to the IP
> of its caller,
> Praveen> which has now been changed to the
> exception cleanup
> Praveen> routine.
>
> Praveen> In this cleanup function, I remove the
> handler. And
> Praveen> then try to get the original IP from the
> global. This
> Praveen> is the place where I'm totally lost.
>
> Praveen> The cause of this problem is, in funcC(),
> I'm calling
> Praveen> one of the libc functions just before
> return. This
> Praveen> changes the "gp". If funcC() were to
> return naturally
> Praveen> to funcB(), there is code in funcB() to
> restore "gp".
> Praveen> But in my implementation, it jumps to the
> cleanup
> Praveen> function and when it tries to access the
> global
> Praveen> variable, it craps out since "gp" is no
> longer correct
> Praveen> for this module.
>
> Praveen> I tried all possible combinations with my
> limited
> Praveen> knowledge and have totally run out of
> ideas. Any
> Praveen> suggestions to fix this issue will be of
> enormous
> Praveen> help.
>
> Praveen> And is there any good reading material
> for itanium 2,
> Praveen> the reference manuals are quite cryptic.
>
>
> Praveen> thank you very much,
> Praveen> Praveen
>
>
> Praveen>
> __________________________________________________
> Praveen> Do you Yahoo!?
> Praveen> Yahoo! Mail Plus - Powerful. Affordable.
> Sign up now.
> Praveen> http://mailplus.yahoo.com
> Praveen>
> _______________________________________________
> Praveen> libunwind mailing list
> Praveen> address@hidden
> Praveen>
>
http://linux.hpl.hp.com/cgi-bin/mailman/listinfo/libunwind
> _______________________________________________
> libunwind mailing list
> address@hidden
>
http://linux.hpl.hp.com/cgi-bin/mailman/listinfo/libunwind
__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com