public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Ed Maste <emaste@SANDVINE.com>
To: "'gcc@gcc.gnu.org'" <gcc@gcc.gnu.org>
Subject: Exception unwinding bug
Date: Thu, 07 Feb 2002 08:50:00 -0000	[thread overview]
Message-ID: <FE045D4D9F7AED4CBFF1B3B813C8533716BC51@mail.sandvine.com> (raw)

I've discovered what I believe to be a bug in the exception unwinding code
of gcc 3.0.3.  I wrote a short test function with just a try & catch in a 
function, and the unwinder crashes at run time.

I've traced the unwinding through to the call to the C++ personality 
function in eh_personality.cc.  At the end of the personality function,
_Unwind_SetGR is called to set up a pointer to the exceptionObject
for the call to __cxa_begin_catch later on (eh_personality.cc:393):

  _Unwind_SetGR (context, __builtin_eh_return_data_regno (0),
		 (_Unwind_Ptr) &xh->unwindHeader);

_Unwind_SetGR takes an _Unwind_Word as its third argument.

I'm using a MIPS processor; sizeof(_Unwind_Ptr) is 32 bits, and 
sizeof(_Unwind_Word) is 64 bits.  _Unwind_Word is an unsigned type
(unwind.h:32):

typedef unsigned _Unwind_Word __attribute__((__mode__(__word__)));

When gcc generates the call to _Unwind_SetGR in the personality 
function, it takes the &xh->unwindHeader and zero-extends it
to 64 bits.  Later on, the generated code for my "catch" calls
__cxa_begin_catch, and the result of the _Unwind_SetGR is in the
a0 register.

__cxa_begin_catch tries to read a value from the exceptionObject.  
The beginning of __cxa_begin_catch looks like this (mips assembly):

__cxa_begin_catch:
addiu           sp,sp,-48
sd              s0,32(sp)
sd              ra,40(sp)
jal             __cxa_get_globals
addiu           s0,a0,-48
lw              v1,20(s0)

So here's the problem: addiu requires its register operand 
to be a valid 64-bit sign extended representation of a 
32-bit value; if it is not, the result is unpredictable[1].  
The zero-extended version that the compiler generates violates 
this rule.  This problem won't show up with user pointers that
end up < 0x80000000; in kernel mode my pointers are 
>= 0x80000000.

It seems that almost all MIPS processors implement addiu as
"do a 32 bit add and then sign extend" so the unpredictable
behaviour produces the expected result.

The processor I'm working with has different unpredictable
behaviour (the result of the addiu still has zeros in bits
63-32), so the "lw" instruction following causes a MIPS 
processor exception.

I can probably work around this by casting the 
&xh->unwindHeader to a signed word in the personality 
function.  I'm not sure how this should be properly
fixed, though, as other architectures might have other 
issues with such a change.

My compiler info:
Configured with: configure --target=mips-wrs-vxworks --enable-threads
Thread model: vxworks
gcc version 3.0.3

[1]
http://www.mips.com/publications/documentation/MD00087-2B-MIPS64BIS-AFP-00.9
5.pdf, page 39

             reply	other threads:[~2002-02-07 16:30 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-02-07  8:50 Ed Maste [this message]
2002-04-25  2:55 ` Exception handling problem on x86-64 Bo Thorsen
2002-04-25 10:08   ` David Edelsohn
2002-04-25 10:33     ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=FE045D4D9F7AED4CBFF1B3B813C8533716BC51@mail.sandvine.com \
    --to=emaste@sandvine.com \
    --cc=gcc@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).