public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call
@ 2005-06-08 6:15 akr at m17n dot org
2005-06-08 6:19 ` [Bug c/21957] " akr at m17n dot org
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: akr at m17n dot org @ 2005-06-08 6:15 UTC (permalink / raw)
To: gcc-bugs
I found that following code causes SEGV on IA-64 Debian GNU/Linux (sarge) with gcc-4.0 -O1. The code uses getcontext and setcontext which is defined by Single Unix Specification. rx1620% cat tst.i typedef long unsigned int size_t; struct ia64_fpreg { union { unsigned long bits[2]; long double __dummy; } u; }; typedef struct sigaltstack { void * ss_sp; int ss_flags; size_t ss_size; } stack_t; struct sigcontext { unsigned long int sc_flags; unsigned long int sc_nat; stack_t sc_stack; unsigned long int sc_ip; unsigned long int sc_cfm; unsigned long int sc_um; unsigned long int sc_ar_rsc; unsigned long int sc_ar_bsp; unsigned long int sc_ar_rnat; unsigned long int sc_ar_ccv; unsigned long int sc_ar_unat; unsigned long int sc_ar_fpsr; unsigned long int sc_ar_pfs; unsigned long int sc_ar_lc; unsigned long int sc_pr; unsigned long int sc_br[8]; unsigned long int sc_gr[32]; struct ia64_fpreg sc_fr[128]; unsigned long int sc_rbs_base; unsigned long int sc_loadrs; unsigned long int sc_ar25; unsigned long int sc_ar26; unsigned long int sc_rsvd[12]; unsigned long int sc_mask; }; typedef struct sigcontext mcontext_t; typedef struct ucontext { union { mcontext_t _mc; struct { unsigned long _pad[(((char *) &((struct sigcontext *) 0)->sc_gr[0]) - (char *) 0)/8]; struct ucontext *_link; } _uc; } _u; } ucontext_t; extern int getcontext (ucontext_t *__ucp) ; extern int setcontext (__const ucontext_t *__ucp) ; int flag; ucontext_t cont; static void f(void) { flag = 1; setcontext(&cont); } static int g(void) { int ret; flag = 0; getcontext(&cont); ret = flag; if (ret == 0) { f(); } return ret; } int main(int argc, char **argv) { g(); return 0; } rx1620% /home/src/gcc/4.0/bin/gcc -v -g -O1 tst.i Using built-in specs. Target: ia64-unknown-linux-gnu Configured with: ../gcc/configure --prefix=/home/src/gcc/4.0 --enable-languages=c Thread model: posix gcc version 4.0.1 20050607 (prerelease) /home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/cc1 -fpreprocessed tst.i -quiet -dumpbase tst.i -auxbase tst -g -O1 -version -o /tmp/ccGs6ixv.s GNU C version 4.0.1 20050607 (prerelease) (ia64-unknown-linux-gnu) compiled by GNU C version 4.0.1 20050607 (prerelease). GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 as -x -o /tmp/ccgROVXU.o /tmp/ccGs6ixv.s /home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/collect2 -dynamic-linker /lib/ld-linux-ia64.so.2 /usr/lib/crt1.o /usr/lib/crti.o /home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtbegin.o -L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1 -L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/../../.. /tmp/ccgROVXU.o -lgcc --as-needed -lgcc_s -lunwind --no-as-needed -lc -lgcc --as-needed -lgcc_s -lunwind --no-as-needed /home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtend.o /usr/lib/crtn.o rx1620% ./a.out zsh: segmentation fault (core dumped) ./a.out rx1620% uname -a Linux rx1620 2.4.25-hpe-9-mckinley-smp #1 SMP Wed Aug 11 11:59:05 UTC 2004 ia64 GNU/Linux ------------------------------------------------ The generated assembly code is follows. | rx1620% /home/src/gcc/4.0/bin/gcc -O1 -S tst.i | rx1620% cat tst.s | .file "tst.i" | .pred.safe_across_calls p1-p5,p16-p63 | .text | .align 16 | .proc f# | f: | .prologue 12, 32 | .save ar.pfs, r33 | alloc r33 = ar.pfs, 0, 3, 1, 0 | mov r34 = r1 | .save rp, r32 | mov r32 = b0 | .body | addl r15 = 1, r0 | addl r14 = @ltoffx(flag#), r1 | ;; | ld8.mov r14 = [r14], flag# | ;; | st4 [r14] = r15 | addl r35 = @ltoffx(cont#), r1 | ;; | ld8.mov r35 = [r35], cont# | br.call.sptk.many b0 = setcontext# | mov r1 = r34 | ;; | mov ar.pfs = r33 | mov b0 = r32 | br.ret.sptk.many b0 | ;; | .endp f# | .align 16 | .proc g# | g: | .prologue 12, 33 | .save ar.pfs, r34 | alloc r34 = ar.pfs, 0, 4, 1, 0 | mov r35 = r1 | .save rp, r33 | mov r33 = b0 | .body | addl r32 = @ltoffx(flag#), r1 | ;; | ld8.mov r32 = [r32], flag# r32 is set. | ;; | st4 [r32] = r0 | addl r36 = @ltoffx(cont#), r1 | ;; | ld8.mov r36 = [r36], cont# | br.call.sptk.many b0 = getcontext# getcontext is called. | mov r1 = r35 | ld4 r32 = [r32] r32 is used. This means that the code expects r32 is preserved after getcontext returns. | ;; | cmp4.ne p6, p7 = 0, r32 | (p6) br.cond.dptk .L4 | br.call.sptk.many b0 = f# | mov r1 = r35 | .L4: | mov r8 = r32 | ;; | mov ar.pfs = r34 | mov b0 = r33 | br.ret.sptk.many b0 | ;; | .endp g# | .align 16 | .global main# | .proc main# | main: | .prologue 12, 32 | .save ar.pfs, r33 | alloc r33 = ar.pfs, 0, 3, 0, 0 | mov r34 = r1 | .save rp, r32 | mov r32 = b0 | .body | ;; | br.call.sptk.many b0 = g# | mov r1 = r34 | mov r8 = r0 | ;; | mov ar.pfs = r33 | mov b0 = r32 | br.ret.sptk.many b0 | ;; | .endp main# | .common flag#,4,4 | .common cont#,2656,16 | .ident "GCC: (GNU) 4.0.1 20050607 (prerelease)" | ------------------- The source code is follows. | rx1620% cat tst.c | #include <ucontext.h> | | int flag; | ucontext_t cont; | | static void f(void) | { | flag = 1; | setcontext(&cont); | } | | static int | g(void) | { | int ret; | | flag = 0; | getcontext(&cont); | ret = flag; | if (ret == 0) { | f(); | } | return ret; | } | | int main(int argc, char **argv) | { | g(); | return 0; | } I investigated the problem as follows. | rx1620% gdb a.out | GNU gdb 6.3-debian | Copyright 2004 Free Software Foundation, Inc. | GDB is free software, covered by the GNU General Public License, and you are | welcome to change it and/or distribute copies of it under certain conditions. | Type "show copying" to see the conditions. | There is absolutely no warranty for GDB. Type "show warranty" for details. | This GDB was configured as "ia64-linux"...Using host libthread_db library "/lib/libthread_db.so.1". | | (gdb) display/i $pc | (gdb) run | Starting program: /home/akr/z/z/a.out | | Program received signal SIGSEGV, Segmentation fault. | g () at tst.i:85 | 85 ret = flag; | 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32] | (gdb) p $r32 | $1 = 0 SEGV is caused because r32 is zero. | (gdb) break *0x4000000000000901 | Breakpoint 1 at 0x4000000000000901: file tst.i, line 85. The breakpoint is on the instruction to use r32. | (gdb) disassemble | Dump of assembler code for function g: | 0x40000000000008c0 <g+0>: [MII] alloc r34=ar.pfs,5,4,0 | 0x40000000000008c1 <g+1>: mov r35=r1 | 0x40000000000008c2 <g+2>: mov r33=b0 | 0x40000000000008d0 <g+16>: [MMI] addl r32=160,r1;; | 0x40000000000008d1 <g+17>: nop.m 0x0 | 0x40000000000008d2 <g+18>: nop.i 0x0;; | 0x40000000000008e0 <g+32>: [MFI] st4 [r32]=r0 | 0x40000000000008e1 <g+33>: nop.f 0x0 | 0x40000000000008e2 <g+34>: addl r36=184,r1;; | 0x40000000000008f0 <g+48>: [MFB] nop.m 0x0 | 0x40000000000008f1 <g+49>: nop.f 0x0 | 0x40000000000008f2 <g+50>: br.call.sptk.many b0=0x40000000000005c0 <_init+208> | 0x4000000000000900 <g+64>: [MMI] mov r1=r35 | 0x4000000000000901 <g+65>: ld4 r32=[r32] | 0x4000000000000902 <g+66>: nop.i 0x0;; | 0x4000000000000910 <g+80>: [MBB] cmp4.eq p7,p6=0,r32 | 0x4000000000000911 <g+81>: (p06) br.cond.dptk.few 0x4000000000000930 <g+112> | 0x4000000000000912 <g+82>: br.call.sptk.many b0=0x4000000000000860 <f> | 0x4000000000000920 <g+96>: [MFB] mov r1=r35 | 0x4000000000000921 <g+97>: nop.f 0x0 | 0x4000000000000922 <g+98>: nop.b 0x0 | 0x4000000000000930 <g+112>: [MMI] mov r8=r32;; | 0x4000000000000931 <g+113>: nop.m 0x0 | 0x4000000000000932 <g+114>: mov.i ar.pfs=r34 | 0x4000000000000940 <g+128>: [MIB] nop.m 0x0 | 0x4000000000000941 <g+129>: mov b0=r33 | 0x4000000000000942 <g+130>: br.ret.sptk.many b0;; | End of assembler dump. | (gdb) break *0x40000000000008f2 | Breakpoint 2 at 0x40000000000008f2: file tst.i, line 84. The breakpoint is on the instruction to call getcontext. | (gdb) run | The program being debugged has been started already. | Start it from the beginning? (y or n) y | Starting program: /home/akr/z/z/a.out | | Breakpoint 2, g () at tst.i:84 | 84 getcontext(&cont); | 1: x/i $pc 0x40000000000008f2 <g+50>: br.call.sptk.many b0=0x40000000000005c0 <_init+208> | (gdb) p $r32 | $2 = 6917529027641086280 r32 is not zero before getcontext call. | (gdb) c | Continuing. | | Breakpoint 1, g () at tst.i:85 | 85 ret = flag; | 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32] | (gdb) p $r32 | $3 = 6917529027641086280 r32 is preserved after first getcontext return. | (gdb) c | Continuing. | | Breakpoint 1, g () at tst.i:85 | 85 ret = flag; | 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32] | (gdb) p $r32 | $4 = 0 r32 is zero after second getcontext return. Note that this return is from setcontext, like longjmp to setjmp. | (gdb) si | | Program received signal SIGSEGV, Segmentation fault. | g () at tst.i:85 | 85 ret = flag; | 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32] I think the getcontext behavior is not a bug because setjmp behaves like so. "Intel(R) Itanium(R) Software Conventions & Runtime Architecture Guide"'s section 10.3 describes setjmp may not preserve the contents of registers in register stack (r32 to r127). http://www.intel.com/design/itanium/downloads/245358.htm It seems that setjmp has no such problem because gcc knows setjmp may return twice. | rx1620% cd /home/src/gcc/4.0/gcc | rx1620% grep -C8 '"setjmp"' gcc/calls.c | tname += 2; | else | tname += 1; | } | | if (tname[0] == 's') | { | if ((tname[1] == 'e' | && (! strcmp (tname, "setjmp") | || ! strcmp (tname, "setjmp_syscall"))) | || (tname[1] == 'i' | && ! strcmp (tname, "sigsetjmp")) | || (tname[1] == 'a' | && ! strcmp (tname, "savectx"))) | flags |= ECF_RETURNS_TWICE; | | if (tname[1] == 'i' So I guess the problem can be fixed if gcc knows getcontext returns twice.
--
Summary: IA-64 register stack is not preserved after getcontext
call
Product: gcc
Version: 4.0.1
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: akr at m17n dot org
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: ia64-unknown-linux-gnu
GCC host triplet: ia64-unknown-linux-gnu
GCC target triplet: ia64-unknown-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug c/21957] IA-64 register stack is not preserved after getcontext call
2005-06-08 6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
@ 2005-06-08 6:19 ` akr at m17n dot org
2005-06-08 6:43 ` [Bug middle-end/21957] " pinskia at gcc dot gnu dot org
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: akr at m17n dot org @ 2005-06-08 6:19 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From akr at m17n dot org 2005-06-08 06:19 -------
Oops. The newlines are squashed. I repeat the report as this comment.
I found that following code causes SEGV on IA-64 Debian GNU/Linux (sarge)
with gcc-4.0 -O1.
The code uses getcontext and setcontext which is defined by
Single Unix Specification.
rx1620% cat tst.i
typedef long unsigned int size_t;
struct ia64_fpreg {
union {
unsigned long bits[2];
long double __dummy;
} u;
};
typedef struct sigaltstack
{
void * ss_sp;
int ss_flags;
size_t ss_size;
} stack_t;
struct sigcontext
{
unsigned long int sc_flags;
unsigned long int sc_nat;
stack_t sc_stack;
unsigned long int sc_ip;
unsigned long int sc_cfm;
unsigned long int sc_um;
unsigned long int sc_ar_rsc;
unsigned long int sc_ar_bsp;
unsigned long int sc_ar_rnat;
unsigned long int sc_ar_ccv;
unsigned long int sc_ar_unat;
unsigned long int sc_ar_fpsr;
unsigned long int sc_ar_pfs;
unsigned long int sc_ar_lc;
unsigned long int sc_pr;
unsigned long int sc_br[8];
unsigned long int sc_gr[32];
struct ia64_fpreg sc_fr[128];
unsigned long int sc_rbs_base;
unsigned long int sc_loadrs;
unsigned long int sc_ar25;
unsigned long int sc_ar26;
unsigned long int sc_rsvd[12];
unsigned long int sc_mask;
};
typedef struct sigcontext mcontext_t;
typedef struct ucontext
{
union
{
mcontext_t _mc;
struct
{
unsigned long _pad[(((char *) &((struct sigcontext *) 0)->sc_gr[0])
- (char *) 0)/8];
struct ucontext *_link;
}
_uc;
}
_u;
}
ucontext_t;
extern int getcontext (ucontext_t *__ucp) ;
extern int setcontext (__const ucontext_t *__ucp) ;
int flag;
ucontext_t cont;
static void f(void)
{
flag = 1;
setcontext(&cont);
}
static int
g(void)
{
int ret;
flag = 0;
getcontext(&cont);
ret = flag;
if (ret == 0) {
f();
}
return ret;
}
int main(int argc, char **argv)
{
g();
return 0;
}
rx1620% /home/src/gcc/4.0/bin/gcc -v -g -O1 tst.i
Using built-in specs.
Target: ia64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/home/src/gcc/4.0 --enable-languages=c
Thread model: posix
gcc version 4.0.1 20050607 (prerelease)
/home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/cc1 -fpreprocessed
tst.i -quiet -dumpbase tst.i -auxbase tst -g -O1 -version -o /tmp/ccGs6ixv.s
GNU C version 4.0.1 20050607 (prerelease) (ia64-unknown-linux-gnu)
compiled by GNU C version 4.0.1 20050607 (prerelease).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
as -x -o /tmp/ccgROVXU.o /tmp/ccGs6ixv.s
/home/src/gcc/4.0/libexec/gcc/ia64-unknown-linux-gnu/4.0.1/collect2
-dynamic-linker /lib/ld-linux-ia64.so.2 /usr/lib/crt1.o /usr/lib/crti.o
/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtbegin.o
-L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1
-L/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/../../..
/tmp/ccgROVXU.o -lgcc --as-needed -lgcc_s -lunwind --no-as-needed -lc -lgcc
--as-needed -lgcc_s -lunwind --no-as-needed
/home/src/gcc/4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.1/crtend.o /usr/lib/crtn.o
rx1620% ./a.out
zsh: segmentation fault (core dumped) ./a.out
rx1620% uname -a
Linux rx1620 2.4.25-hpe-9-mckinley-smp #1 SMP Wed Aug 11 11:59:05 UTC 2004 ia64
GNU/Linux
------------------------------------------------
The generated assembly code is follows.
| rx1620% /home/src/gcc/4.0/bin/gcc -O1 -S tst.i
| rx1620% cat tst.s
| .file "tst.i"
| .pred.safe_across_calls p1-p5,p16-p63
| .text
| .align 16
| .proc f#
| f:
| .prologue 12, 32
| .save ar.pfs, r33
| alloc r33 = ar.pfs, 0, 3, 1, 0
| mov r34 = r1
| .save rp, r32
| mov r32 = b0
| .body
| addl r15 = 1, r0
| addl r14 = @ltoffx(flag#), r1
| ;;
| ld8.mov r14 = [r14], flag#
| ;;
| st4 [r14] = r15
| addl r35 = @ltoffx(cont#), r1
| ;;
| ld8.mov r35 = [r35], cont#
| br.call.sptk.many b0 = setcontext#
| mov r1 = r34
| ;;
| mov ar.pfs = r33
| mov b0 = r32
| br.ret.sptk.many b0
| ;;
| .endp f#
| .align 16
| .proc g#
| g:
| .prologue 12, 33
| .save ar.pfs, r34
| alloc r34 = ar.pfs, 0, 4, 1, 0
| mov r35 = r1
| .save rp, r33
| mov r33 = b0
| .body
| addl r32 = @ltoffx(flag#), r1
| ;;
| ld8.mov r32 = [r32], flag#
r32 is set.
| ;;
| st4 [r32] = r0
| addl r36 = @ltoffx(cont#), r1
| ;;
| ld8.mov r36 = [r36], cont#
| br.call.sptk.many b0 = getcontext#
getcontext is called.
| mov r1 = r35
| ld4 r32 = [r32]
r32 is used.
This means that the code expects r32 is preserved after getcontext returns.
| ;;
| cmp4.ne p6, p7 = 0, r32
| (p6) br.cond.dptk .L4
| br.call.sptk.many b0 = f#
| mov r1 = r35
| .L4:
| mov r8 = r32
| ;;
| mov ar.pfs = r34
| mov b0 = r33
| br.ret.sptk.many b0
| ;;
| .endp g#
| .align 16
| .global main#
| .proc main#
| main:
| .prologue 12, 32
| .save ar.pfs, r33
| alloc r33 = ar.pfs, 0, 3, 0, 0
| mov r34 = r1
| .save rp, r32
| mov r32 = b0
| .body
| ;;
| br.call.sptk.many b0 = g#
| mov r1 = r34
| mov r8 = r0
| ;;
| mov ar.pfs = r33
| mov b0 = r32
| br.ret.sptk.many b0
| ;;
| .endp main#
| .common flag#,4,4
| .common cont#,2656,16
| .ident "GCC: (GNU) 4.0.1 20050607 (prerelease)"
|
-------------------
The source code is follows.
| rx1620% cat tst.c
| #include <ucontext.h>
|
| int flag;
| ucontext_t cont;
|
| static void f(void)
| {
| flag = 1;
| setcontext(&cont);
| }
|
| static int
| g(void)
| {
| int ret;
|
| flag = 0;
| getcontext(&cont);
| ret = flag;
| if (ret == 0) {
| f();
| }
| return ret;
| }
|
| int main(int argc, char **argv)
| {
| g();
| return 0;
| }
I investigated the problem as follows.
| rx1620% gdb a.out
| GNU gdb 6.3-debian
| Copyright 2004 Free Software Foundation, Inc.
| GDB is free software, covered by the GNU General Public License, and you are
| welcome to change it and/or distribute copies of it under certain conditions.
| Type "show copying" to see the conditions.
| There is absolutely no warranty for GDB. Type "show warranty" for details.
| This GDB was configured as "ia64-linux"...Using host libthread_db library
"/lib/libthread_db.so.1".
|
| (gdb) display/i $pc
| (gdb) run
| Starting program: /home/akr/z/z/a.out
|
| Program received signal SIGSEGV, Segmentation fault.
| g () at tst.i:85
| 85 ret = flag;
| 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32]
| (gdb) p $r32
| $1 = 0
SEGV is caused because r32 is zero.
| (gdb) break *0x4000000000000901
| Breakpoint 1 at 0x4000000000000901: file tst.i, line 85.
The breakpoint is on the instruction to use r32.
| (gdb) disassemble
| Dump of assembler code for function g:
| 0x40000000000008c0 <g+0>: [MII] alloc r34=ar.pfs,5,4,0
| 0x40000000000008c1 <g+1>: mov r35=r1
| 0x40000000000008c2 <g+2>: mov r33=b0
| 0x40000000000008d0 <g+16>: [MMI] addl r32=160,r1;;
| 0x40000000000008d1 <g+17>: nop.m 0x0
| 0x40000000000008d2 <g+18>: nop.i 0x0;;
| 0x40000000000008e0 <g+32>: [MFI] st4 [r32]=r0
| 0x40000000000008e1 <g+33>: nop.f 0x0
| 0x40000000000008e2 <g+34>: addl r36=184,r1;;
| 0x40000000000008f0 <g+48>: [MFB] nop.m 0x0
| 0x40000000000008f1 <g+49>: nop.f 0x0
| 0x40000000000008f2 <g+50>: br.call.sptk.many
b0=0x40000000000005c0 <_init+208>
| 0x4000000000000900 <g+64>: [MMI] mov r1=r35
| 0x4000000000000901 <g+65>: ld4 r32=[r32]
| 0x4000000000000902 <g+66>: nop.i 0x0;;
| 0x4000000000000910 <g+80>: [MBB] cmp4.eq p7,p6=0,r32
| 0x4000000000000911 <g+81>: (p06) br.cond.dptk.few
0x4000000000000930 <g+112>
| 0x4000000000000912 <g+82>: br.call.sptk.many
b0=0x4000000000000860 <f>
| 0x4000000000000920 <g+96>: [MFB] mov r1=r35
| 0x4000000000000921 <g+97>: nop.f 0x0
| 0x4000000000000922 <g+98>: nop.b 0x0
| 0x4000000000000930 <g+112>: [MMI] mov r8=r32;;
| 0x4000000000000931 <g+113>: nop.m 0x0
| 0x4000000000000932 <g+114>: mov.i ar.pfs=r34
| 0x4000000000000940 <g+128>: [MIB] nop.m 0x0
| 0x4000000000000941 <g+129>: mov b0=r33
| 0x4000000000000942 <g+130>: br.ret.sptk.many b0;;
| End of assembler dump.
| (gdb) break *0x40000000000008f2
| Breakpoint 2 at 0x40000000000008f2: file tst.i, line 84.
The breakpoint is on the instruction to call getcontext.
| (gdb) run
| The program being debugged has been started already.
| Start it from the beginning? (y or n) y
| Starting program: /home/akr/z/z/a.out
|
| Breakpoint 2, g () at tst.i:84
| 84 getcontext(&cont);
| 1: x/i $pc 0x40000000000008f2 <g+50>: br.call.sptk.many
b0=0x40000000000005c0 <_init+208>
| (gdb) p $r32
| $2 = 6917529027641086280
r32 is not zero before getcontext call.
| (gdb) c
| Continuing.
|
| Breakpoint 1, g () at tst.i:85
| 85 ret = flag;
| 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32]
| (gdb) p $r32
| $3 = 6917529027641086280
r32 is preserved after first getcontext return.
| (gdb) c
| Continuing.
|
| Breakpoint 1, g () at tst.i:85
| 85 ret = flag;
| 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32]
| (gdb) p $r32
| $4 = 0
r32 is zero after second getcontext return.
Note that this return is from setcontext, like longjmp to setjmp.
| (gdb) si
|
| Program received signal SIGSEGV, Segmentation fault.
| g () at tst.i:85
| 85 ret = flag;
| 1: x/i $pc 0x4000000000000901 <g+65>: ld4 r32=[r32]
I think the getcontext behavior is not a bug because setjmp behaves like so.
"Intel(R) Itanium(R) Software Conventions & Runtime Architecture Guide"'s
section 10.3 describes setjmp may not preserve the contents of registers in
register stack (r32 to r127).
http://www.intel.com/design/itanium/downloads/245358.htm
It seems that setjmp has no such problem because
gcc knows setjmp may return twice.
| rx1620% cd /home/src/gcc/4.0/gcc
| rx1620% grep -C8 '"setjmp"' gcc/calls.c
| tname += 2;
| else
| tname += 1;
| }
|
| if (tname[0] == 's')
| {
| if ((tname[1] == 'e'
| && (! strcmp (tname, "setjmp")
| || ! strcmp (tname, "setjmp_syscall")))
| || (tname[1] == 'i'
| && ! strcmp (tname, "sigsetjmp"))
| || (tname[1] == 'a'
| && ! strcmp (tname, "savectx")))
| flags |= ECF_RETURNS_TWICE;
|
| if (tname[1] == 'i'
So I guess the problem can be fixed if gcc knows getcontext returns twice.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
2005-06-08 6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
2005-06-08 6:19 ` [Bug c/21957] " akr at m17n dot org
@ 2005-06-08 6:43 ` pinskia at gcc dot gnu dot org
2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
2005-06-29 3:50 ` akr at m17n dot org
3 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-06-08 6:43 UTC (permalink / raw)
To: gcc-bugs
--
What |Removed |Added
----------------------------------------------------------------------------
Component|c |middle-end
Keywords| |wrong-code
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
2005-06-08 6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
2005-06-08 6:19 ` [Bug c/21957] " akr at m17n dot org
2005-06-08 6:43 ` [Bug middle-end/21957] " pinskia at gcc dot gnu dot org
@ 2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
2005-06-29 3:50 ` akr at m17n dot org
3 siblings, 0 replies; 6+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-06-20 17:05 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From pinskia at gcc dot gnu dot org 2005-06-20 17:04 -------
Hmm, why do you think getcontext should return twice?
It does not, GCC is emmitting correct asm for a normal function, why should getcontext be different?
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
2005-06-08 6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
` (2 preceding siblings ...)
2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
@ 2005-06-29 3:50 ` akr at m17n dot org
3 siblings, 0 replies; 6+ messages in thread
From: akr at m17n dot org @ 2005-06-29 3:50 UTC (permalink / raw)
To: gcc-bugs
------- Additional Comments From akr at m17n dot org 2005-06-29 03:50 -------
I think getcontext should return twice because getcontext is similar to setjmp.
First, getcontext returns from usual function call.
Second, getcontext returns from setcontext.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Bug middle-end/21957] IA-64 register stack is not preserved after getcontext call
[not found] <bug-21957-2489@http.gcc.gnu.org/bugzilla/>
@ 2005-11-09 12:08 ` ebotcazou at gcc dot gnu dot org
0 siblings, 0 replies; 6+ messages in thread
From: ebotcazou at gcc dot gnu dot org @ 2005-11-09 12:08 UTC (permalink / raw)
To: gcc-bugs
------- Comment #4 from ebotcazou at gcc dot gnu dot org 2005-11-09 12:08 -------
*** This bug has been marked as a duplicate of 22127 ***
--
ebotcazou at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |RESOLVED
Resolution| |DUPLICATE
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21957
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2005-11-09 12:08 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-08 6:15 [Bug c/21957] New: IA-64 register stack is not preserved after getcontext call akr at m17n dot org
2005-06-08 6:19 ` [Bug c/21957] " akr at m17n dot org
2005-06-08 6:43 ` [Bug middle-end/21957] " pinskia at gcc dot gnu dot org
2005-06-20 17:05 ` pinskia at gcc dot gnu dot org
2005-06-29 3:50 ` akr at m17n dot org
[not found] <bug-21957-2489@http.gcc.gnu.org/bugzilla/>
2005-11-09 12:08 ` ebotcazou at gcc dot gnu dot org
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).