Bug 14646 - [x32] backtrace doesn't work
Summary: [x32] backtrace doesn't work
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: backtrace (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 7.5
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-09-29 18:04 UTC by H.J. Lu
Modified: 2012-11-10 00:52 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2012-09-29 18:04:56 UTC
On Linux/x32 with glibc compiled with GCC 4.7.2, I
got

[hjl@gnu-tools-1 tmp]$ cat x.c
int
main ()
{
  return 0;
}
[hjl@gnu-tools-1 tmp]$ gcc -mx32 -g x.c 
[hjl@gnu-tools-1 tmp]$ gdb a.out 
GNU gdb (GDB) 7.5.50.20120925-cvs
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/a.out...done.
(gdb) b __init_misc
Function "__init_misc" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (__init_misc) pending.
(gdb) r
Starting program: /tmp/a.out 

Breakpoint 1, 0xf7b1cbc0 in __init_misc () from /libx32/libc.so.6
(gdb) bt
#0  0xf7b1cbc0 in __init_misc () from /libx32/libc.so.6
#1  0xf7a45b96 in _init () from /libx32/libc.so.6
#2  0x00000004 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) 

Linux/x86-64 works much better:
[hjl@gnu-tools-1 tmp]$ gcc -g x.c -o 64
[hjl@gnu-tools-1 tmp]$ gdb 64
GNU gdb (GDB) 7.5.50.20120925-cvs
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/64...done.
(gdb) b __init_misc
Function "__init_misc" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (__init_misc) pending.
(gdb) r
Starting program: /tmp/64 

Breakpoint 1, 0x00000035978f1540 in __init_misc () from /lib64/libc.so.6
(gdb) bt
#0  0x00000035978f1540 in __init_misc () from /lib64/libc.so.6
#1  0x0000003597821519 in _init () from /lib64/libc.so.6
#2  0x000000359740f850 in call_init.part.0 () from /lib64/ld-linux-x86-64.so.2
#3  0x000000359740f950 in _dl_init_internal () from /lib64/ld-linux-x86-64.so.2
#4  0x000000359740152a in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffe386 in ?? ()
#7  0x0000000000000000 in ?? ()
(gdb)
Comment 1 H.J. Lu 2012-09-29 23:25:39 UTC
hjl/x32/gdb_7_4-branch git branch at

http://sourceware.org/git/?p=gdb.git;a=summary

works fine.
Comment 2 H.J. Lu 2012-09-30 21:16:04 UTC
amd64_x32_init_abi has

  tdep->sp_regnum_from_eax = AMD64_RSP_REGNUM;
  tdep->pc_regnum_from_eax = AMD64_RIP_REGNUM;

But unwind frame info is based on the real RSP/RIP
registers.  Pseudo sp/pc registers don't work with
frame related codes:

[hjl@gnu-tools-1 gdb]$ egrep "pc_regnum|sp_regnum" *fram*.c 
dwarf2-frame.c:  if (regnum == gdbarch_pc_regnum (gdbarch))
dwarf2-frame.c:  else if (regnum == gdbarch_sp_regnum (gdbarch))
dwarf2-frame.c:	      == gdbarch_sp_regnum (gdbarch)))
dwarf2-frame-tailcall.c:  if (regnum == gdbarch_pc_regnum (this_gdbarch))
dwarf2-frame-tailcall.c:  else if (cache->prev_sp_p && regnum == gdbarch_sp_regnum (this_gdbarch))
dwarf2-frame-tailcall.c:      int sp_regnum;
dwarf2-frame-tailcall.c:      sp_regnum = gdbarch_sp_regnum (prev_gdbarch);
dwarf2-frame-tailcall.c:      if (sp_regnum == -1)
dwarf2-frame-tailcall.c:      prev_sp = frame_unwind_register_unsigned (this_frame, sp_regnum);
frame.c:      && gdbarch_pc_regnum (gdbarch) >= 0
frame.c:				      gdbarch_pc_regnum (gdbarch),
frame.c:				      gdbarch_pc_regnum (gdbarch),
frame.c:     the gdbarch_sp_regnum register is meaningful.  */
frame.c:  if (gdbarch_sp_regnum (gdbarch) >= 0)
frame.c:					gdbarch_sp_regnum (gdbarch));
[hjl@gnu-tools-1 gdb]$ 

It is to print

(gdb) p $sp
$1 = (void *) 0xffffd028

instead of

(gdb) p $sp
$1 = 4294955048

But it breaks frame unwind.
Comment 3 Jan Kratochvil 2012-10-01 16:13:27 UTC
Not taking this bug but it would be good to have a -nostdlib testcase for this regression as it should be compatible with common x86_64 OSes.
Comment 4 H.J. Lu 2012-10-01 16:31:07 UTC
(In reply to comment #3)
> Not taking this bug but it would be good to have a -nostdlib testcase for this
> regression as it should be compatible with common x86_64 OSes.

How should a -nostdlib testcase work? I believe such testcase only works
in x32 environment.
Comment 5 Jan Kratochvil 2012-10-01 16:55:45 UTC
While normal GDB testfiles run only on the native arch I believe x32 testfiles could have an exception to run (also) with x86_64 testsuite run target.

Fedora 16 x86_64
gcc -o x32 x32.c -Wall -g -nostdlib -mx32
gdb ./x32
----------------------------
int f (void) {
  volatile int i = 4, j = 2;
  return i * 10 + j; }
int _start (void) {
  f ();
  return 0; }
----------------------------
gcc -dumpmachine
x86_64-unknown-linux-gnu
----------------------------
GNU gdb (GDB) 7.5.50.20120930-cvs
This GDB was configured as "x86_64-unknown-linux-gnu".
(gdb) b _start
Breakpoint 1 at 0x4000c1: file x32.c, line 5.
(gdb) r
Starting program: /home/jkratoch/t/x32 

Breakpoint 1, _start () at x32.c:5
5	  f ();
(gdb) s
f () at x32.c:2
2	  volatile int i = 4, j = 2;
(gdb) fini
Run till exit from #0  f () at x32.c:2
_start () at x32.c:6
6	  return 0; }
Value returned is $1 = 42
(gdb) _
Comment 6 H.J. Lu 2012-10-01 17:14:35 UTC
(In reply to comment #5)
> While normal GDB testfiles run only on the native arch I believe x32 testfiles
> could have an exception to run (also) with x86_64 testsuite run target.
> 
> Fedora 16 x86_64
> gcc -o x32 x32.c -Wall -g -nostdlib -mx32

How did you enable x32 support in your kernel?
My request to enable x32 in Fedora 18 kernel
was rejected.
Comment 7 Jan Kratochvil 2012-10-01 17:20:15 UTC
Sorry I do not know more:
$ grep -i x32 /boot/config-3.4.11-1.fc16.x86_64 
# CONFIG_X86_X32 is not set
Comment 8 H.J. Lu 2012-10-01 17:33:35 UTC
(In reply to comment #7)
> Sorry I do not know more:
> $ grep -i x32 /boot/config-3.4.11-1.fc16.x86_64 
> # CONFIG_X86_X32 is not set

This is very odd. Does your GCC really support -mx32?
What does "file x32" say?
Comment 9 Jan Kratochvil 2012-10-01 17:59:26 UTC
OK, you are right; GCC has built it as x32 but the kernel executes it as x86_64:

$ file x32
x32: ELF 32-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

(gdb) disas
Dump of assembler code for function f:
=> 0x00400094 <+0>:	push   %rbp
[...]
(gdb) p/x $sp
$1 = 0xffffce20
(gdb) stepi
0x00400095	1	int f (void) {
(gdb) p/x $sp
$2 = 0xffffce18
Comment 10 H.J. Lu 2012-10-01 18:42:07 UTC
(In reply to comment #9)
> OK, you are right; GCC has built it as x32 but the kernel executes it as
> x86_64:
> 
> $ file x32
> x32: ELF 32-bit LSB executable, x86-64, version 1 (SYSV), statically linked,
> not stripped
> 

Your kernel has partial x32 support.  I don't think we should
count on it.  It is better to run x32 tests in x32 environment.
Comment 11 Sourceware Commits 2012-10-15 20:37:44 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2012-10-15 20:37:39

Modified files:
	gdb            : ChangeLog amd64-tdep.c i386-tdep.c i386-tdep.h 

Log message:
	Remove sp_regnum_from_eax and pc_regnum_from_eax
	
	PR backtrace/14646
	PR gdb/14647
	* i386-tdep.h (gdbarch_tdep): Remove sp_regnum_from_eax and
	pc_regnum_from_eax.
	* i386-tdep.c (i386_gdbarch_init): Don't use sp_regnum_from_eax
	nor pc_regnum_from_eax.
	* amd64-tdep.c (amd64_x32_init_abi): Don't set sp_regnum_from_eax
	nor pc_regnum_from_eax.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.14736&r2=1.14737
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/amd64-tdep.c.diff?cvsroot=src&r1=1.112&r2=1.113
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/i386-tdep.c.diff?cvsroot=src&r1=1.357&r2=1.358
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/i386-tdep.h.diff?cvsroot=src&r1=1.80&r2=1.81
Comment 12 Sourceware Commits 2012-11-10 00:50:53 UTC
CVSROOT:	/cvs/src
Module name:	src
Branch: 	gdb_7_5-branch
Changes by:	hjl@sourceware.org	2012-11-10 00:50:46

Modified files:
	gdb            : ChangeLog amd64-tdep.c i386-tdep.c i386-tdep.h 

Log message:
	Remove sp_regnum_from_eax and pc_regnum_from_eax
	
	PR backtrace/14646
	PR gdb/14647
	* i386-tdep.h (gdbarch_tdep): Remove sp_regnum_from_eax and
	pc_regnum_from_eax.
	* i386-tdep.c (i386_gdbarch_init): Don't use sp_regnum_from_eax
	nor pc_regnum_from_eax.
	* amd64-tdep.c (amd64_x32_init_abi): Don't set sp_regnum_from_eax
	nor pc_regnum_from_eax.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.14469.2.37&r2=1.14469.2.38
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/amd64-tdep.c.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.109&r2=1.109.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/i386-tdep.c.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.355&r2=1.355.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/src/gdb/i386-tdep.h.diff?cvsroot=src&only_with_tag=gdb_7_5-branch&r1=1.80&r2=1.80.2.1
Comment 13 H.J. Lu 2012-11-10 00:52:07 UTC
Fixed on 7.5 branch.