Eric Botcazou - Unwinding through signal handlers on IA-64/Linux (original) (raw)
This is the mail archive of the gcc@gcc.gnu.orgmailing list for the GCC project.
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
| Other format: | [Raw text] |
- From: Eric Botcazou
- To: gcc at gcc dot gnu dot org
- Date: Fri, 4 Nov 2005 20:36:30 +0100
- Subject: Unwinding through signal handlers on IA-64/Linux
Hi,
It works if the unwind library is HP's libunwind (aka system libunwind) but doesn't if the unwind library is the bundled one (config/ia64/unwind-ia64.c). That's with a 3.4.5pre-based compiler on SLES 9, but the problem is very likely present on all branches.
The bottom line is that the CFM register is incorrectly restored: it is loaded with the value of the AR.PFS register when the signal is raised.
Breakpoint 3, 0x4000000000003300 in _ada_p () (gdb) info reg cfm cfm 0x287 647 (gdb) info reg pfs pfs 0xc000000000000388 -4611686018427387000 (gdb) continue Continuing.
Program received signal SIGSEGV, Segmentation fault. 0x4000000000003300 in _ada_p () (gdb) Continuing.
Breakpoint 1, 0x40000000000033f2 in _ada_p () (gdb) info reg cfm cfm 0x388 904
Debug session with the same executable using HP's libunwind:
Breakpoint 3, 0x4000000000003300 in _ada_p () (gdb) info reg cfm cfm 0x287 647 (gdb) info reg pfs pfs 0xc000000000000388 -4611686018427387000 (gdb) continue Continuing.
Program received signal SIGSEGV, Segmentation fault. 0x4000000000003300 in _ada_p () (gdb) Continuing.
Breakpoint 1, 0x40000000000033f2 in _ada_p () (gdb) info reg cfm cfm 0x287 647
Now the unwinder gets it almost right, that is fs->curr.reg[UNW_REG_PFS] holds the right values (val = 224, where = UNW_WHERE_SPREL, when = -1). But there are these lines in ia64_handle_unwabi:
/* pfs_loc already set above. Without this pfs_loc would point
incorrectly to sc_cfm instead of sc_ar_pfs. */
fs->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE;The problem is that we want pfs_loc to essentially[1] point to sc_cfm, which is the saved CFM in the signal context, because we use the target AR.PFS to restore the CFM with the help of br.ret; we certainly don't want it to point to the saved AR.PFS in the signal context, which is a dead value if a register frame has been allocated[2].
These lines look very questionable to me; if they are removed, all works fine for the attached testcase (compile with -gnatp). Maybe some confusion comes from
context->pfs_loc = &(sc->sc_ar_pfs);a few lines above, which is a dead statement if considered alone.
Can anyone shed some light on this? Thanks in advance.
[1] essentially because we probably would want pfs_loc to point to a CFM+EC value. But I skimmed through HP's libunwind and I didn't find any attempt to put together a full AR.PFS value from saved CFM and EC.
[2] if a register frame has not been allocated then AR.PFS is live in the procedure and would need to be restored too. Incidentally, the current code probably works in that case, but I think it cannot happen in practice.
-- Eric Botcazou
with Ada.Text_IO;
procedure P is type Int_Ptr is access all Integer; Data : Int_Ptr := null; begin Data.all := 0; exception when others => Ada.Text_IO.Put_Line ("Exception handled"); end P;
- Follow-Ups:
- Re: Unwinding through signal handlers on IA-64/Linux
* From: Jim Wilson
- Re: Unwinding through signal handlers on IA-64/Linux
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |