[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#312188: getcontext/setcontext doesn't restore r32 on IA-64.



Package: libc6.1
Version: 2.3.2.ds1-22

I found that getcontext/setcontext doesn't restore the register r32 on IA-64.

| 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
| rx1620% cat /etc/debian_version 
| 3.1

The problem can be reproduced as follows.

| rx1620% cat tst.c 
| #include <stdlib.h>
| #include <stdio.h>
| #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) {
|     printf("first\n");
|     f();
|   }
|   else {
|     printf("second\n");
|   }
|   return ret;
| }
| 
| int main(int argc, char **argv)
| {
|   g();
|   return 0;
| }
| rx1620% gcc -v -g -O2 tst.c
| Reading specs from /usr/lib/gcc-lib/ia64-linux/3.3.5/specs
| Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --enable-__cxa_atexit --with-system-zlib --enable-nls --without-included-gettext --with-system-libunwind --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc ia64-linux
| Thread model: posix
| gcc version 3.3.5 (Debian 1:3.3.5-13)
|  /usr/lib/gcc-lib/ia64-linux/3.3.5/cc1 -quiet -v -D__GNUC__=3 -D__GNUC_MINOR__=3 -D__GNUC_PATCHLEVEL__=5 tst.c -quiet -dumpbase tst.c -auxbase tst -g -O2 -version -o /tmp/cciD2htF.s
| GNU C version 3.3.5 (Debian 1:3.3.5-13) (ia64-linux)
|         compiled by GNU C version 3.3.5 (Debian 1:3.3.5-13).
| GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
| ignoring nonexistent directory "/usr/ia64-linux/include"
| #include "..." search starts here:
| #include <...> search starts here:
|  /usr/local/include
|  /usr/lib/gcc-lib/ia64-linux/3.3.5/include
|  /usr/include
| End of search list.
|  as -x -o /tmp/ccOESoXi.o /tmp/cciD2htF.s
|  /usr/lib/gcc-lib/ia64-linux/3.3.5/collect2 -dynamic-linker /lib/ld-linux-ia64.so.2 /usr/lib/gcc-lib/ia64-linux/3.3.5/../../../crt1.o /usr/lib/gcc-lib/ia64-linux/3.3.5/../../../crti.o /usr/lib/gcc-lib/ia64-linux/3.3.5/crtbegin.o -L/usr/lib/gcc-lib/ia64-linux/3.3.5 -L/usr/lib/gcc-lib/ia64-linux/3.3.5/../../.. /tmp/ccOESoXi.o -lgcc --as-needed -lgcc_s -lunwind --no-as-needed -lc -lgcc --as-needed -lgcc_s -lunwind --no-as-needed /usr/lib/gcc-lib/ia64-linux/3.3.5/crtend.o /usr/lib/gcc-lib/ia64-linux/3.3.5/../../../crtn.o
| rx1620% ./a.out 
| first
| zsh: segmentation fault (core dumped)  ./a.out

It shouldn't segmentation fault, I think.

I invesitigated 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/a.out 
| first
| 
| Program received signal SIGSEGV, Segmentation fault.
| g () at tst.c:21
| 21        ret = flag;
| 1: x/i $pc  0x4000000000000921 <g+81>:              ld4 r32=[r32]

It is reproducible on gdb.

| (gdb) p $r32
| $1 = 0

SEGV is caused by dereferencing r32 which is zero.

| (gdb) disassemble 
| Dump of assembler code for function g:
| 0x40000000000008d0 <g+0>:       [MMB]       alloc r34=ar.pfs,5,4,0
| 0x40000000000008d1 <g+1>:                   addl r14=224,r1
| 0x40000000000008d2 <g+2>:                   nop.b 0x0
| 0x40000000000008e0 <g+16>:      [MII]       mov r35=r1
| 0x40000000000008e1 <g+17>:                  mov r33=b0;;
| 0x40000000000008e2 <g+18>:                  nop.i 0x0
| 0x40000000000008f0 <g+32>:      [MII]       mov r36=r14
| 0x40000000000008f1 <g+33>:                  addl r14=200,r1;;
| 0x40000000000008f2 <g+34>:                  nop.i 0x0
| 0x4000000000000900 <g+48>:      [MMI]       mov r32=r14;;
| 0x4000000000000901 <g+49>:                  st4 [r32]=r0
| 0x4000000000000902 <g+50>:                  nop.i 0x0
| 0x4000000000000910 <g+64>:      [MIB]       nop.m 0x0
| 0x4000000000000911 <g+65>:                  nop.i 0x0
| 0x4000000000000912 <g+66>:                  br.call.sptk.many b0=0x40000000000005c0 <_init+208>;;

This calls getcontext.

| 0x4000000000000920 <g+80>:      [MMI]       mov r1=r35
| 0x4000000000000921 <g+81>:                  ld4 r32=[r32]

SEGV point.

| 0x4000000000000922 <g+82>:                  nop.i 0x0;;
| 0x4000000000000930 <g+96>:      [MII]       addl r14=72,r1
| 0x4000000000000931 <g+97>:                  addl r15=80,r1
| 0x4000000000000932 <g+98>:                  cmp4.eq p7,p6=0,r32;;
| 0x4000000000000940 <g+112>:     [MMB]       ld8 r14=[r14]
| 0x4000000000000941 <g+113>:                 ld8 r36=[r15]
| 0x4000000000000942 <g+114>:           (p06) br.cond.dptk.few 0x4000000000000990 <g+192>;;
| 0x4000000000000950 <g+128>:     [MIB]       mov r36=r14
| 0x4000000000000951 <g+129>:                 nop.i 0x0
| 0x4000000000000952 <g+130>:                 br.call.sptk.many b0=0x4000000000000600 <_init+272>;;
| 0x4000000000000960 <g+144>:     [MIB]       mov r1=r35
| 0x4000000000000961 <g+145>:                 nop.i 0x0
| 0x4000000000000962 <g+146>:                 br.call.sptk.many b0=0x4000000000000870 <f>;;
| 0x4000000000000970 <g+160>:     [MMI]       mov r8=r32
| 0x4000000000000971 <g+161>:                 mov r1=r35
| 0x4000000000000972 <g+162>:                 mov.i ar.pfs=r34
| 0x4000000000000980 <g+176>:     [MIB]       nop.m 0x0
| 0x4000000000000981 <g+177>:                 mov b0=r33
| 0x4000000000000982 <g+178>:                 br.ret.sptk.many b0;;
| ---Type <return> to continue, or q <return> to quit---q
| Quit
| (gdb) break *0x4000000000000921
| Breakpoint 1 at 0x4000000000000921: file tst.c, line 21.
| (gdb) break *0x4000000000000912
| Breakpoint 2 at 0x4000000000000912: file tst.c, line 20.

Set breakpoints for the SEGV point and the getcontext call.

| (gdb) run
| The program being debugged has been started already.
| Start it from the beginning? (y or n) y
| Starting program: /home/akr/z/a.out 
| 
| Breakpoint 2, g () at tst.c:20
| 20        getcontext(&cont);
| 1: x/i $pc  0x4000000000000912 <g+66>:              br.call.sptk.many b0=0x40000000000005c0 <_init+208>;;
| (gdb) p $r32
| $3 = 6917529027641086440

r32 is not zero before getcontext call.

| (gdb) ni
| 20        getcontext(&cont);
| 1: x/i $pc  0x4000000000000920 <g+80>:  [MMI]       mov r1=r35
| (gdb) ni
| 
| Breakpoint 1, g () at tst.c:21
| 21        ret = flag;
| 1: x/i $pc  0x4000000000000921 <g+81>:              ld4 r32=[r32]
| (gdb) p $r32
| $4 = 6917529027641086440

r32 is not zero too after first getcontext return.

| (gdb) c
| Continuing.
| first
| 
| Breakpoint 1, g () at tst.c:21
| 21        ret = flag;
| 1: x/i $pc  0x4000000000000921 <g+81>:              ld4 r32=[r32]
| (gdb) p $r32
| $5 = 0

r32 is zero after second getcontext return.

| (gdb) si
| 
| Program received signal SIGSEGV, Segmentation fault.
| g () at tst.c:21
| 21        ret = flag;
| 1: x/i $pc  0x4000000000000921 <g+81>:              ld4 r32=[r32]
| (gdb) 

SEGV caused by dereferencing zero.

| rx1620% ldd a.out 
|         libc.so.6.1 => /lib/libc.so.6.1 (0x2000000000040000)
|         /lib/ld-linux-ia64.so.2 => /lib/ld-linux-ia64.so.2 (0x2000000000000000)
| rx1620% dpkg -S /lib/libc.so.6.1 
| libc6.1: /lib/libc.so.6.1
| rx1620% dpkg -s libc6.1
| Package: libc6.1
| Status: install ok installed
| Priority: required
| Section: base
| Installed-Size: 22052
| Maintainer: GNU Libc Maintainers <debian-glibc@lists.debian.org>
| Architecture: ia64
| Source: glibc
| Version: 2.3.2.ds1-22
| Replaces: ldso (<= 1.9.11-9), timezone, timezones, gconv-modules, libtricks, netkit-rpc, netbase (<< 4.0), libc6.1-dev (<< 2.3.2.ds1-14)
| Provides: glibc-2.3.2.ds1-22
| Depends: libdb1-compat
| Suggests: locales, glibc-doc
| Conflicts: strace (<< 4.0-0), libnss-db (<= 2.2-6.1.1), timezone, timezones, gconv-modules, libtricks, libc6.1-doc, netkit-rpc, wine (<< 0.0.20031118-1), cyrus-imapd (<< 1.5.19-15)
| Description: GNU C Library: Shared libraries and Timezone data
|  Contains the standard libraries that are used by nearly all programs on
|  the system. This package includes shared versions of the standard C library
|  and the standard math library, as well as many others.
|  Timezone data is also included.
-- 
Tanaka Akira



Reply to: