Stack Unwinding - OS2

This is a discussion on Stack Unwinding - OS2 ; Anyone have any code to unwind the stack? I seem to be running into a
problem when I trap ^C when the program is performing I/O and in the
kernel. When I try to back up a couple of stack ...

Stack Unwinding

Anyone have any code to unwind the stack? I seem to be running into a
problem when I trap ^C when the program is performing I/O and in the
kernel. When I try to back up a couple of stack frame past the trap
handler I run into problems, although I haven't yet determined exactly
what is wrong, whether 16-bit code, switching from the kernel stack, or
what-have-you.

I need to be able to back up from the trap handler to whatever user code
was previously executing.

Re: Stack Unwinding

Suddenly, Peter Flass sprang forth and uttered these pithy words:
> Anyone have any code to unwind the stack? I seem to be running into a
> problem when I trap ^C when the program is performing I/O and in the
> kernel. When I try to back up a couple of stack frame past the trap
> handler I run into problems, although I haven't yet determined exactly
> what is wrong, whether 16-bit code, switching from the kernel stack, or
> what-have-you.
>
> I need to be able to back up from the trap handler to whatever user code
> was previously executing.

Search for exceptq
Though I don't know whether it handles the OS callgates or whatever
--
aaronl at consultant dot com
For every expert, there is an equal and
opposite expert. - Arthur C. Clarke

Re: Stack Unwinding

In , on 12/18/2004
at 11:43 AM, Peter Flass said:
>Anyone have any code to unwind the stack? I seem to be running into a
>problem when I trap ^C when the program is performing I/O and in the
>kernel. When I try to back up a couple of stack frame past the trap
>handler I run into problems, although I haven't yet determined exactly
>what is wrong, whether 16-bit code, switching from the kernel stack, or
>what-have-you.
>I need to be able to back up from the trap handler to whatever user code
>was previously executing.

How are you trying to debug this? With printf code or with a debugger?
Offhand, I suspect it would be easy to trace with the kernel debugger, if
you can reproduce the error easily enough.

Exceptq is probably not going to help. It does a pretty good job of
generating a backtrace, but it is, as it's name implies, an exception
handler so it may very will hide whatever problem your ctrl-c handler has.

XWorkPlace has good backtrace code that you might be able to integrate
into your application, if you don't might the license.

You might want to describe the "problem" in a bit more detail. Is this a
multi-threading issue?

FWIW, your Ctrl-C handler excutes on the thread's ring3 stack. The ring0
stack is not involved when your hanlder runs.

Re: Stack Unwinding

This is a single-threaded app. I'm debugging using printf - actually
DosWrite. I set my exception handler, read from stdin with no
redirection, so that stdin is the console, and then ^C. My exception
handler gets control and tries to unwind the stack. I backtrack to the
exception handler and then a couple of more stack frames, probably to
some of OS/2's setup for the exception handler and then die, or rather
the EBP chain seems to go off somwhere in never-never land. It is
interesting that I originally tested this by having my program go into
an endless loop, and the ^C logic worked just fine, as all the other
exceptions I've encountered seem to. This is the first situation I've
encountered where it doesn't work.

I've also played around using the Watcom debugger, and visually seen the
same situation, so it doesn't appear to be a simple program bug, more
likely something I'm missing. My next step will be to print out the
entire stack (It isn't very deep at this point) and see if there's
something obvious. I've also looked at EBP from the exception handler's
context record, and it also seems to point to the same place on the
stack. A second thing I tried (it looked possible that OS/2 may have
stuck one or two 16-bit frames on the stack) was to assume I had a "BP"
value and rebuild "EBP" myself, but again no good. I'll have to wait
until tomorrow to do more testing.

Steven Levine wrote:
> In , on 12/18/2004
> at 11:43 AM, Peter Flass said:
>
>
>>Anyone have any code to unwind the stack? I seem to be running into a
>>problem when I trap ^C when the program is performing I/O and in the
>>kernel. When I try to back up a couple of stack frame past the trap
>>handler I run into problems, although I haven't yet determined exactly
>>what is wrong, whether 16-bit code, switching from the kernel stack, or
>>what-have-you.
>
>
>>I need to be able to back up from the trap handler to whatever user code
>>was previously executing.
>
>
> How are you trying to debug this? With printf code or with a debugger?
> Offhand, I suspect it would be easy to trace with the kernel debugger, if
> you can reproduce the error easily enough.
>
> Exceptq is probably not going to help. It does a pretty good job of
> generating a backtrace, but it is, as it's name implies, an exception
> handler so it may very will hide whatever problem your ctrl-c handler has.
>
> XWorkPlace has good backtrace code that you might be able to integrate
> into your application, if you don't might the license.
>
> You might want to describe the "problem" in a bit more detail. Is this a
> multi-threading issue?
>
> FWIW, your Ctrl-C handler excutes on the thread's ring3 stack. The ring0
> stack is not involved when your hanlder runs.
>
> Steven
>

Re: Stack Unwinding

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Steven Levine], who wrote in article <41c544ee$2$fgrir53$mr2ice@news.west.earthlink.net>:
> Exceptq is probably not going to help. It does a pretty good job of
> generating a backtrace, but it is, as it's name implies, an exception
> handler so it may very will hide whatever problem your ctrl-c handler has.

My impression is that ctrl-c handler is an exception handler; so
exceptq should work inside it; anyway, one can peruse the source of
exceptq...

Some semi-educated guesses (I never actually needed anything else than
reading the code of exceptq),
Ilya

Re: Stack Unwinding

In , on 12/19/2004
at 09:03 PM, Peter Flass said:
>This is a single-threaded app. I'm debugging using printf - actually
>DosWrite. I set my exception handler, read from stdin with no
>redirection, so that stdin is the console, and then ^C. My exception
>handler gets control and tries to unwind the stack. I backtrack to the
>exception handler and then a couple of more stack frames, probably to
>some of OS/2's setup for the exception handler and then die, or rather
>the EBP chain seems to go off somwhere in never-never land.

This is expected, if I understand what you are saying. There is no direct
connection between the exception handler's stack and the application
stack. If you unwind the exception handler's stack, you are going to end
up in the kernel's exception dispatch code. Depending on how you created
the handler, you might wander through the C runtime's exception handler
dispatch code as well.

If what you are trying to determine is what code that was executing in
some other process, at the time you pressed ctrl-c, this is not so simple.
The kernel could be doing any number of things that the time the keyboard
interrupt occurs. It might not even be running ring3 code.
>interesting that I originally tested this by having my program go into
>an endless loop, and the ^C logic worked just fine, as all the other
>exceptions I've encountered seem to.

I think I see what you are looking at. If I display the call stack with
icsdebug while in an exception handler, it does appear that that the
handler would return is to your code. Of course this is not the actual
code path that occurs. I didn't have time to analyze the raw stack to see
if icsdebug was doing any magic when interpreting the stack. I know that
exceptq contains some non-obvious code in its WalkStack routine.

Re: Stack Unwinding

[A complimentary Cc of this posting was NOT [per weedlist] sent to
Steven Levine], who wrote in article <41c735c0$2$fgrir53$mr2ice@news.west.earthlink.net>:
> >My impression is that ctrl-c handler is an exception handler; so exceptq
> >should work inside it
>
> Both are exception handlers. They are going to execute serially, unless
> Peter generates and exception inside his exception handler.

If he *installs* the exceptq handler - yes. But this was not my suggestion.

He can *call* the exceptq handler; or he can *use the code* of it.
> FWIW, exceptq does not process Ctrl-C beyond passing it on with a
> XCPT_CONTINUE_SEARCH return code.

Given the source, this should be easy to change, right?

Hope this helps,
Ilya

P.S. Anyway, IIRC, the exception info should contain the ESP at the
time of exception. My impression is that one should unwind the
stack using *this* value, not the *current* ESP.

Re: Stack Unwinding

Thanks to those who have mentioned execptq (on Hobbes as except3, BTW).
I didn't have much time today to look at it, but I grabbed a copy and
found WalkStack, which hopefully will provide me the answer. I also
printed out the stack, and indeed found two distinct chains of EBP's --
mine from the top of the stack down to DosRead, then some stuff, then
the exception handler's chain (16-bit, apparently, as I thought) at the
bottom of the stack. I hope exceptq will show me how to connect the two.

My other choice would be to do more work -- possibly save the address of
my ^C routine as I go, so I would be able to grab it in the exception
handler without having to actually unwind the stack, but I don't like
that approach for several reasons.

I'll let everyone know when/if I figure out what is going on.

Steven Levine wrote:
> In , on 12/19/2004
> at 09:03 PM, Peter Flass said:
>
>
>>This is a single-threaded app. I'm debugging using printf - actually
>>DosWrite. I set my exception handler, read from stdin with no
>>redirection, so that stdin is the console, and then ^C. My exception
>>handler gets control and tries to unwind the stack. I backtrack to the
>>exception handler and then a couple of more stack frames, probably to
>>some of OS/2's setup for the exception handler and then die, or rather
>>the EBP chain seems to go off somwhere in never-never land.
>
>
> This is expected, if I understand what you are saying. There is no direct
> connection between the exception handler's stack and the application
> stack. If you unwind the exception handler's stack, you are going to end
> up in the kernel's exception dispatch code. Depending on how you created
> the handler, you might wander through the C runtime's exception handler
> dispatch code as well.
>
> If what you are trying to determine is what code that was executing in
> some other process, at the time you pressed ctrl-c, this is not so simple.
> The kernel could be doing any number of things that the time the keyboard
> interrupt occurs. It might not even be running ring3 code.
>
>
>>interesting that I originally tested this by having my program go into
>>an endless loop, and the ^C logic worked just fine, as all the other
>>exceptions I've encountered seem to.
>
>
> I think I see what you are looking at. If I display the call stack with
> icsdebug while in an exception handler, it does appear that that the
> handler would return is to your code. Of course this is not the actual
> code path that occurs. I didn't have time to analyze the raw stack to see
> if icsdebug was doing any magic when interpreting the stack. I know that
> exceptq contains some non-obvious code in its WalkStack routine.
>
> Steven
>

Re: Stack Unwinding

Thanks to all who helped. I spent a lot more time on this than it's
worth, and it looks like the answer is" "it can't be done'. Apparently
signal exceptions break the stack backchain. I've looked at the stack
from here to next Tuesday, and can't find a link. OS/2 creates a
special stack frame with the return address=0, and at this point the
EBP backchain begins to get screwy. *Possibly* there are a couple of
16-bit frames, or possibly not, I can't really tell, but after two of
these EBP gets lost and there's no further valid backchain anyhow.

I've come up with another way to handle the signal exceptions, so this
is annoying but not a fatal problem.

Re: Stack Unwinding

Thanks to all who helped. I spent a lot more time on this than it's
worth, and it looks like the answer is" "it can't be done'. Apparently
signal exceptions break the stack backchain. I've looked at the stack
from here to next Tuesday, and can't find a link. OS/2 creates a
special stack frame with the return address=0, and at this point the
EBP backchain begins to get screwy. *Possibly* there are a couple of
16-bit frames, or possibly not, I can't really tell, but after two of
these EBP gets lost and there's no further valid backchain anyhow.