public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* Examining copied stack contents
@ 2010-07-03 10:48 Martin Schröder
  2010-07-05  4:54 ` support biarch gcore? Jon Zhou
  2010-07-05 18:50 ` Examining copied stack contents Petr Hluzín
  0 siblings, 2 replies; 18+ messages in thread
From: Martin Schröder @ 2010-07-03 10:48 UTC (permalink / raw)
  To: gdb

Hello everyone.

I'm currently implementing a high-level debugger based on GDB for a 
coroutine-based simulation framework. The platform is GNU/Linux on x86.

That framework implements coroutines by using the C/C++ setjmp/longjmp 
instructions and by copying the call stack that is used by each 
coroutine to dynamically allocated memory on the heap. It's this latter 
aspect that gives me terrible headaches in GDB.

My question is simply: Is it possible to point GDB to the copied 
contents of the call stack and tell it to print out the information 
contained therein?

The documentation [1] does contain the following note:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
frame addr
f addr
Select the frame at address addr. This is useful mainly if the chaining 
of stack frames has been damaged by a bug, making it impossible for gdb 
to assign numbers properly to all frames. In addition, this can be 
useful when your program has multiple stacks and switches between them.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Additionally, the docs about the "info frame" command also say that it 
accepts memory addresses as arguments.


Unfortunately, this does not seem to work as well as I anticipated. I 
tried several versions of the GDB, from 6.8 to the newest 7.1, but they 
all exhibit the same issues.

When I stop the program directly after the call stack was saved, the 
situation presents itself as follows:

The stack pointer register is at 0xbfffeec0. The first two stack frames 
return the following data:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) info frame 0
Stack frame at 0xbfffeef0:
 eip = 0x805a972 in [CODE LINE]; saved eip 0x805a588
 called by frame at 0xbfffef30
 source language c++.
 Arglist at 0xbfffeee8, args: this=0x80b3238
 Locals at 0xbfffeee8, Previous frame's sp is 0xbfffeef0
 Saved registers:
  ebp at 0xbfffeee8, eip at 0xbfffeeec

(gdb) info frame 1
Stack frame at 0xbfffef30:
 eip = 0x805a588 in [CODE LINE]; saved eip 0x806b2a6
 called by frame at 0xbfffef70, caller of frame at 0xbfffeef0
 source language c++.
 Arglist at 0xbfffef28, args: this=0x80b2bd8
 Locals at 0xbfffef28, Previous frame's sp is 0xbfffef30
 Saved registers:
  ebx at 0xbfffef20, ebp at 0xbfffef28, esi at 0xbfffef24, eip at 
0xbfffef2c
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

The program copied the whole stack (including a bit of safety margin) 
beginning with the address 0xbfffeedf to the address 0x80b39c8.

Now, if I tell GDB to print information about the stack frame located at 
0xbfffeef0, it does so correctly:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) info frame 0xbfffeef0
Stack frame at 0xbfffeef0:
 eip = 0x805a972 in [CODE LINE]; saved eip 0x805a588
 called by frame at 0xbfffef30
 source language c++.
 Arglist at 0xbfffeee8, args: this=0x80b3238
 Locals at 0xbfffeee8, Previous frame's sp is 0xbfffeef0
 Saved registers:
  ebp at 0xbfffeee8, eip at 0xbfffeeec

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

But if I point it to the exact copy of that frame, beginning with 
0x80b39d9, I get the following "fail safe" information that the GDB also 
prints when I point it to *any* arbitrary address:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) info frame 0x80b39d9
Stack frame at 0x80b39d9:
 eip = 0x0; saved eip 0x80b39c8
 called by frame at 0xbfffeef0
 Arglist at 0xbfffeebc, args:
 Locals at 0xbfffeebc, Previous frame's sp is 0xbfffeec4
 Saved registers:
  eip at 0xbfffeec0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

But if I examine the memory ranges, they are absolutely identical:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) x/8x 0x80b39d9
0x80b39d9: 0x080b3238 0x080b2bd8 0x080b2ca4 0x080b2ca4
0x80b39e9: 0x0021a73c 0x080b2bc8 0x080b3238 0x00000000
(gdb) x/8x 0xbfffeef0
0xbfffeef0: 0x080b3238 0x080b2bd8 0x080b2ca4 0x080b2ca4
0xbfffef00: 0x0021a73c 0x080b2bc8 0x080b3238 0x00000000
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Obviously, the GDB doesn't even attempt to interpret the given address 
as a stack frame. I am aware that the GDB needs debugging symbols to 
make any sense out of the stack (after all, the frame size depends on 
the actual call they represent); and also that the addresses inside the 
copied stack can't be followed, because they still point to the original 
memory addresses.

But I'm also aware that the GDB *should be* able to do what I want it to 
do. For one, the documentation explicitly mentions that the feature 
works with programs that utilize multiple stacks. Furthermore, the GDB 
is also able to debug Multi-Threaded programs, which also need to save 
the call stack to dynamic heap memory.



So, my question is: Is it possible to examine the copied stack? And if 
yes, what do I need to give to the GDB to allow it?



Thanks in advance,
    Martin Schröder.


[1] - http://sourceware.org/gdb/current/onlinedocs/gdb/Selection.html 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* support biarch gcore?
  2010-07-03 10:48 Examining copied stack contents Martin Schröder
@ 2010-07-05  4:54 ` Jon Zhou
  2010-07-05  7:12   ` Jan Kratochvil
  2010-07-05 18:50 ` Examining copied stack contents Petr Hluzín
  1 sibling, 1 reply; 18+ messages in thread
From: Jon Zhou @ 2010-07-05  4:54 UTC (permalink / raw)
  To: gdb

Hi there

Regarding this case, does the current release solve it ? I just tried the patch but looks it doesn't work

Thanks
jon


http://sourceware.org/ml/gdb/2009-03/msg00010.html

Re: Problem viewing gcore of 32 bit binary on 64 bit SLES 10.1, gdb 6.6
From: Jan Kratochvil <jan dot kratochvil at redhat dot com> 
To: Shane G <pachoo at gmail dot com> 
Cc: gdb at sourceware dot org 
Date: Tue, 3 Mar 2009 00:10:28 +0100 
Subject: Re: Problem viewing gcore of 32 bit binary on 64 bit SLES 10.1, gdb 6.6 
References: <985ad4e70903021500u594a4c4w30eff9ae287f5e8d@mail.gmail.com> 

--------------------------------------------------------------------------------

On Tue, 03 Mar 2009 00:00:57 +0100, Shane G wrote:
> I'm unable to view any usable information from a gcore that I've run
> against a 32 bit binary running on a 64 bit version of SLES 10.1.

from your description IMO the core file is primarily generated wrong by gcore.
If you somewhere get a correct 32bit core file expecting gdb-x86_64 probably
reads it fine on your system.


> This GDB was configured as "x86_64-suse-linux"...

At least in
http://download.opensuse.org/repositories/home:/dgollub/openSUSE_Factory/src/gdb-6.8-14.80.src.rpm

I see no gcore biarch patch and FSF GDB does not support biarch gcore (in this
case i386-on-x86_64).  You may port there the patch:
http://cvs.fedora.redhat.com/viewvc/rpms/gdb/devel/gdb-6.5-gcore-i386-on-amd64.patch?revision=1.6



Regards,
Jan




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-05  4:54 ` support biarch gcore? Jon Zhou
@ 2010-07-05  7:12   ` Jan Kratochvil
  2010-07-05 11:55     ` Mark Kettenis
  0 siblings, 1 reply; 18+ messages in thread
From: Jan Kratochvil @ 2010-07-05  7:12 UTC (permalink / raw)
  To: Jon Zhou; +Cc: gdb

On Mon, 05 Jul 2010 06:52:37 +0200, Jon Zhou wrote:
> Regarding this case, does the current release solve it ? I just tried the
> patch but looks it doesn't work

Issue is tracked at:
	amd64 gdb generates corrupted 32bit core file
	http://sourceware.org/bugzilla/show_bug.cgi?id=11467

There was a patchset by H.J.Lu but it did not make it in FSF GDB:
	PATCH: PR corefiles/11467: amd64 gdb generates corrupted 32bit core file
	http://sourceware.org/ml/gdb-patches/2010-04/msg00315.html
with the last mail of this thread:
	http://sourceware.org/ml/gdb-patches/2010-04/msg00427.html
	> Please stop sending diffs until you understand how the code is
	> supposed to work.

The Fedora patch
	http://cvs.fedoraproject.org/viewvc/rpms/gdb/devel/gdb-6.5-gcore-i386-on-amd64.patch?content-type=text%2Fplain&view=co

will be rebased or replaced by H.J.Lu's one for gdb-7.2-pre by 2010-07-27.


Thanks,
Jan


> References: <4A25DE879BC24E8DAEAEBD722E363025@igor>
> In-Reply-To: <4A25DE879BC24E8DAEAEBD722E363025@igor>

Please do not reply to the existing mail "Examining copied stack contents"
when you start a new thread.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-05  7:12   ` Jan Kratochvil
@ 2010-07-05 11:55     ` Mark Kettenis
  2010-07-06 20:48       ` Ulrich Weigand
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Kettenis @ 2010-07-05 11:55 UTC (permalink / raw)
  To: jan.kratochvil; +Cc: Jon.Zhou, gdb

> Date: Mon, 5 Jul 2010 09:12:35 +0200
> From: Jan Kratochvil <jan.kratochvil@redhat.com>
> 
> On Mon, 05 Jul 2010 06:52:37 +0200, Jon Zhou wrote:
> > Regarding this case, does the current release solve it ? I just tried the
> > patch but looks it doesn't work
> 
> Issue is tracked at:
> 	amd64 gdb generates corrupted 32bit core file
> 	http://sourceware.org/bugzilla/show_bug.cgi?id=11467
> 
> There was a patchset by H.J.Lu but it did not make it in FSF GDB:
> 	PATCH: PR corefiles/11467: amd64 gdb generates corrupted 32bit core file
> 	http://sourceware.org/ml/gdb-patches/2010-04/msg00315.html
> with the last mail of this thread:
> 	http://sourceware.org/ml/gdb-patches/2010-04/msg00427.html
> 	> Please stop sending diffs until you understand how the code is
> 	> supposed to work.
> 
> The Fedora patch
> 	http://cvs.fedoraproject.org/viewvc/rpms/gdb/devel/gdb-6.5-gcore-i386-on-amd64.patch?content-type=text%2Fplain&view=co
> 
> will be rebased or replaced by H.J.Lu's one for gdb-7.2-pre by 2010-07-27.

The proper way to fix the issue is to add proper cross-core support to
BFD for i386 and amd64 like was done for powerpc/powerpc64 a couple of
years ago.  See the thread starting at:

http://sourceware.org/ml/binutils/2010-04/msg00225.html

Perhaps I need to resubmit that diff now that things have settled down
a bit.

With that diff in, there still is a GDB issue that needs to be
resolved.  The core generation code in
linux-nat.c:linux_nat_do_thread_registers() allocates a buffer of type
gdb_gregset_t to store the registers.  Since its size differs between
i386 and amd64 the size passed to _reget_from_core_section() is always
the size of the amd64 gdb_gregset_t.  Since the current code checks
for an exact match, it fails to return a regset, and things go
downhill from there.

Fixing the code in linux-nat.c is a bit nasty:

* The definition of the 32-bit version of gdb_gregset_t isn't readily
  available on 64-bit systems.

* The code is used on all Linux platforms and only a few of them are
  bi-arch.

An alternative solution would be to make _regset_from_core_section() a
little bit more forgiving.  The diff below works since the size of the
amd64 gdb_gregset_t is larger than the i386-version.


2010-07-05  Mark Kettenis  <kettenis@gnu.org>

        * i386-tdep.c (i386_supply_gregset, i386_collect_gregset)
        (i386_regset_from_core_section): Relax check for size of .reg
        section.

Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.316
diff -u -p -r1.316 i386-tdep.c
--- i386-tdep.c	22 Jun 2010 02:15:45 -0000	1.316
+++ i386-tdep.c	5 Jul 2010 11:50:55 -0000
@@ -2775,7 +2775,7 @@ i386_supply_gregset (const struct regset
   const gdb_byte *regs = gregs;
   int i;
 
-  gdb_assert (len == tdep->sizeof_gregset);
+  gdb_assert (len >= tdep->sizeof_gregset);
 
   for (i = 0; i < tdep->gregset_num_regs; i++)
     {
@@ -2799,7 +2799,7 @@ i386_collect_gregset (const struct regse
   gdb_byte *regs = gregs;
   int i;
 
-  gdb_assert (len == tdep->sizeof_gregset);
+  gdb_assert (len >= tdep->sizeof_gregset);
 
   for (i = 0; i < tdep->gregset_num_regs; i++)
     {
@@ -2880,7 +2880,7 @@ i386_regset_from_core_section (struct gd
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (strcmp (sect_name, ".reg") == 0 && sect_size == tdep->sizeof_gregset)
+  if (strcmp (sect_name, ".reg") == 0 && sect_size >= tdep->sizeof_gregset)
     {
       if (tdep->gregset == NULL)
 	tdep->gregset = regset_alloc (gdbarch, i386_supply_gregset,








^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Examining copied stack contents
  2010-07-03 10:48 Examining copied stack contents Martin Schröder
  2010-07-05  4:54 ` support biarch gcore? Jon Zhou
@ 2010-07-05 18:50 ` Petr Hluzín
  2010-07-05 20:18   ` Martin Schröder
  2010-07-07 17:29   ` Martin Schröder
  1 sibling, 2 replies; 18+ messages in thread
From: Petr Hluzín @ 2010-07-05 18:50 UTC (permalink / raw)
  To: Martin Schröder; +Cc: gdb

Hello Martin and list

On 3 July 2010 12:46, Martin Schröder <gschroeder@onlinehome.de> wrote:
> Hello everyone.
>
> I'm currently implementing a high-level debugger based on GDB for a
> coroutine-based simulation framework. The platform is GNU/Linux on x86.
>
> That framework implements coroutines by using the C/C++ setjmp/longjmp
> instructions and by copying the call stack that is used by each coroutine to
> dynamically allocated memory on the heap. It's this latter aspect that gives
> me terrible headaches in GDB.
>
> My question is simply: Is it possible to point GDB to the copied contents of
> the call stack and tell it to print out the information contained therein?

(Note I am not familiar in x86 stack-walking stuff.)

In general a debugger needs at least a stack pointer and an
instruction pointer to get a backtrace. If the function containing the
IP uses a frame pointer (a debugger should be able to tell you that)
then debugger needs to know the FP. Which register contains the FP
depends on the prologue type chosen by compiler (on x86 it is always
EBP). Command "info frame <address>" may assume IP is pointed to by
SP. So there are at least 2 arguments (FP+SP) to be provided on any
arch.

Therefore I suspect "info frame <address>" is not general enough to be
used in your case.

> That framework implements coroutines by using the C/C++ setjmp/longjmp
> instructions and by copying the call stack that is used by each coroutine to
> dynamically allocated memory on the heap.

Beware that a function compiled without -fomit-frame-pointer saves SP
to stack and gdb uses the value to obtain stack-trace (this is not
quite exact). If you copy a stack somewhere and use gdb to walk the
stack there then gdb will try to use SP values pointing to the "old"
stack memory.
(And you cannot resume execution of the stack while in the new memory.)

> But I'm also aware that the GDB *should be* able to do what I want it to do.
> For one, the documentation explicitly mentions that the feature works with
> programs that utilize multiple stacks. Furthermore, the GDB is also able to
> debug Multi-Threaded programs, which also need to save the call stack to
> dynamic heap memory.

When doing multithreaded programs gdb gets register values from
pthread library (or linux kernel?) or by remote target command. And
the stack frames stay where they were created - they are not copied.

> So, my question is: Is it possible to examine the copied stack? And if yes,
> what do I need to give to the GDB to allow it?

I do not know. Someone else have to answer that.

-- 
Petr Hluzin

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Examining copied stack contents
  2010-07-05 18:50 ` Examining copied stack contents Petr Hluzín
@ 2010-07-05 20:18   ` Martin Schröder
  2010-07-05 20:27     ` Joel Brobecker
  2010-07-07 17:29   ` Martin Schröder
  1 sibling, 1 reply; 18+ messages in thread
From: Martin Schröder @ 2010-07-05 20:18 UTC (permalink / raw)
  To: gdb

Petr Hluzín wrote:
>
> (Note I am not familiar in x86 stack-walking stuff.)
>
> In general a debugger needs at least a stack pointer and an
> instruction pointer to get a backtrace. If the function containing the
> IP uses a frame pointer (a debugger should be able to tell you that)
> then debugger needs to know the FP. Which register contains the FP
> depends on the prologue type chosen by compiler (on x86 it is always
> EBP). Command "info frame <address>" may assume IP is pointed to by
> SP. So there are at least 2 arguments (FP+SP) to be provided on any
> arch.
>
> Therefore I suspect "info frame <address>" is not general enough to be
> used in your case.

Mhhhm, I also suspected as much, but the docs [1] only point out four
architectures where more than just the SP is necessary: SPARC (FP + SP),
MIPS & Alpha (PC + SP) and the 29k architecture (Register SP + Memory SP
+ PC).

The docs did not mention x86, which made me abandon that line of
thinking. Anyway, I'll try to play around with the additional parameters
and see if they change anything.

[1] - http://www.circlemud.org/cdp/gdb/gdb_7.html#SEC43

>> That framework implements coroutines by using the C/C++
>> setjmp/longjmp instructions and by copying the call stack that is
>> used by each coroutine to dynamically allocated memory on the heap.
>
> Beware that a function compiled without -fomit-frame-pointer saves SP
> to stack and gdb uses the value to obtain stack-trace (this is not
> quite exact). If you copy a stack somewhere and use gdb to walk the
> stack there then gdb will try to use SP values pointing to the "old"
> stack memory.
> (And you cannot resume execution of the stack while in the new
> memory.)

I also assumed that GDB will parse the contents of the stack to get the
proper sequence of frames. But that's why I deliberately chose to break
the simulation when the stack contents were copied but not yet
overwritten. Thus, even *if* the GDB parses the new stack and
subsequently accesses the old areas, everything should still work,
because the old stack's still in place.

It seems to me that the stack walking algorithm notices some kind of
error, but simply fails to relay it to me. After all, no matter WHAT
address I give GDB, it always returns the same, useless data and never
even once throws an error.


>> But I'm also aware that the GDB *should be* able to do what I want
>> it to do. For one, the documentation explicitly mentions that the
>> feature works with programs that utilize multiple stacks.
>> Furthermore, the GDB is also able to debug Multi-Threaded programs,
>> which also need to save the call stack to dynamic heap memory.
>
> When doing multithreaded programs gdb gets register values from
> pthread library (or linux kernel?) or by remote target command. And
> the stack frames stay where they were created - they are not copied.

Yes, but the app still needs to switch from one stack to another during
execution, which is by all means very similar to copying the stack
somewhere else and resuming execution from there (something I don't need
to do; I merely need to examine the copy, not run it).

So, whatevery causes GDB to accept the move to another stack should also
enable it to move to the /same/ stack at another memory location. I
mean, I could easily live with manipulating a few registers and memory
chunks so that the GDB believes that the new stack location is valid.

If only the documentation would include which data stores are read
during stack traversal! Unfortunately, my attempts at digging around in
the source code was equally fruitless in that regard.


But thanks for pointing out that GDB most likely analyzes the register
values to do its job. I'll see if I can manipulate them to get GDB to do
something sensible.


>> So, my question is: Is it possible to examine the copied stack? And
>> if yes, what do I need to give to the GDB to allow it?
>
> I do not know. Someone else have to answer that.

Thanks anyway. You've already helped me enough so that I found a few
more approaches to testing GDB's features.


So long,
    Martin Schröder.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Examining copied stack contents
  2010-07-05 20:18   ` Martin Schröder
@ 2010-07-05 20:27     ` Joel Brobecker
  0 siblings, 0 replies; 18+ messages in thread
From: Joel Brobecker @ 2010-07-05 20:27 UTC (permalink / raw)
  To: Martin Schr?der; +Cc: gdb

There are several possible ways to do callstack unwinding on each
architecture.  The prefered way is to rely on DWARF frame info, but
we otherwise fallback on other methods (either native unwinding
info, or if all else fails, prologue parsing). That's why the GDB
code for each architecture registers "sniffers" which will tell GDB
for each frame which unwinder would be best to use.  The result also
depends on the type of frame, since signal frames often require their
own unwinder.

I recommend that you have a look at i386-tdep.c, and in particular
the various functions specified in the i386_frame_unwind structure.
That should help you find out what is actually going on inside GDB.

-- 
Joel

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-05 11:55     ` Mark Kettenis
@ 2010-07-06 20:48       ` Ulrich Weigand
  2010-07-06 21:29         ` Mark Kettenis
  0 siblings, 1 reply; 18+ messages in thread
From: Ulrich Weigand @ 2010-07-06 20:48 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: jan.kratochvil, Jon.Zhou, gdb

Mark Kettenis wrote:

> Fixing the code in linux-nat.c is a bit nasty:
> 
> * The definition of the 32-bit version of gdb_gregset_t isn't readily
>   available on 64-bit systems.
> 
> * The code is used on all Linux platforms and only a few of them are
>   bi-arch.

This was really supposed to be fixed by the gdbarch_core_regset_sections
mechanism, which provides the names and sizes of all register sets
expected in a core file for the current architecture.

However, it seems that this mechanism isn't currently used for .reg
itself, only for the other sections.  While it is true that .reg needs
to be handled somewhat specially, it should still be possible to get
its size from gdbarch_core_regset_sections, and thus avoid the need
to use the gdb_gregset_t type.

Unfortunately, it also turned out that the section sizes provided for
.reg in those targets that have gdbarch_core_regset_sections, while
currently unused, were also nearly all wrong ...

The following patch fixes those sizes, and changes linux-nat.c to
use them.

Tested on powerpc64-linux (-m64 / -m32), amd64-linux (-m64 / -m32),
and i386-linux with no regressions.  In fact, it appears to fix all
pre-existing gcore-related failures on amd64 -m32 ...

Thoughts?

Bye,
Ulrich


ChangeLog:

	* linux-nat.c (linux_nat_do_thread_registers): Use section size
	from gdbarch_core_regset_sections also for .reg if present.

	* amd64-linux-tdep.c (amd64_linux_regset_sections): Fix incorrect
	section size for .reg.
	* ppc-linux-tdep.c (ppc_linux_vsx_regset_sections): Likewise.
	(ppc_linux_vmx_regset_sections): Likewise.
	(ppc_linux_fp_regset_sections): Likewise.
	(ppc64_linux_vsx_regset_sections): New variable.
	(ppc64_linux_vmx_regset_sections): Likewise.
	(ppc64_linux_fp_regset_sections): Likewise.
	(ppc_linux_init_abi): Install core_regset_section lists appropriate
	for current word size.


Index: gdb/amd64-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/amd64-linux-tdep.c,v
retrieving revision 1.37
diff -u -p -r1.37 amd64-linux-tdep.c
--- gdb/amd64-linux-tdep.c	22 Apr 2010 20:02:55 -0000	1.37
+++ gdb/amd64-linux-tdep.c	6 Jul 2010 20:24:45 -0000
@@ -52,7 +52,7 @@
 /* Supported register note sections.  */
 static struct core_regset_section amd64_linux_regset_sections[] =
 {
-  { ".reg", 144, "general-purpose" },
+  { ".reg", 27 * 8, "general-purpose" },
   { ".reg2", 512, "floating-point" },
   { ".reg-xstate", I386_XSTATE_MAX_SIZE, "XSAVE extended state" },
   { NULL, 0 }
Index: gdb/linux-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-nat.c,v
retrieving revision 1.172
diff -u -p -r1.172 linux-nat.c
--- gdb/linux-nat.c	1 Jul 2010 15:36:16 -0000	1.172
+++ gdb/linux-nat.c	6 Jul 2010 20:24:46 -0000
@@ -4134,8 +4134,6 @@ linux_nat_do_thread_registers (bfd *obfd
 			       char *note_data, int *note_size,
 			       enum target_signal stop_signal)
 {
-  gdb_gregset_t gregs;
-  gdb_fpregset_t fpregs;
   unsigned long lwp = ptid_get_lwp (ptid);
   struct gdbarch *gdbarch = target_gdbarch;
   struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
@@ -4153,21 +4151,6 @@ linux_nat_do_thread_registers (bfd *obfd
   core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
   sect_list = gdbarch_core_regset_sections (gdbarch);
 
-  if (core_regset_p
-      && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
-						     sizeof (gregs))) != NULL
-      && regset->collect_regset != NULL)
-    regset->collect_regset (regset, regcache, -1,
-			    &gregs, sizeof (gregs));
-  else
-    fill_gregset (regcache, &gregs, -1);
-
-  note_data = (char *) elfcore_write_prstatus (obfd,
-					       note_data,
-					       note_size,
-					       lwp,
-					       stop_signal, &gregs);
-
   /* The loop below uses the new struct core_regset_section, which stores
      the supported section names and sizes for the core file.  Note that
      note PRSTATUS needs to be treated specially.  But the other notes are
@@ -4175,12 +4158,6 @@ linux_nat_do_thread_registers (bfd *obfd
   if (core_regset_p && sect_list != NULL)
     while (sect_list->sect_name != NULL)
       {
-	/* .reg was already handled above.  */
-	if (strcmp (sect_list->sect_name, ".reg") == 0)
-	  {
-	    sect_list++;
-	    continue;
-	  }
 	regset = gdbarch_regset_from_core_section (gdbarch,
 						   sect_list->sect_name,
 						   sect_list->size);
@@ -4188,12 +4165,16 @@ linux_nat_do_thread_registers (bfd *obfd
 	gdb_regset = xmalloc (sect_list->size);
 	regset->collect_regset (regset, regcache, -1,
 				gdb_regset, sect_list->size);
-	note_data = (char *) elfcore_write_register_note (obfd,
-							  note_data,
-							  note_size,
-							  sect_list->sect_name,
-							  gdb_regset,
-							  sect_list->size);
+
+	if (strcmp (sect_list->sect_name, ".reg") == 0)
+	  note_data = (char *) elfcore_write_prstatus
+				(obfd, note_data, note_size,
+				 lwp, stop_signal, gdb_regset);
+	else
+	  note_data = (char *) elfcore_write_register_note
+				(obfd, note_data, note_size,
+				 sect_list->sect_name, gdb_regset,
+				 sect_list->size);
 	xfree (gdb_regset);
 	sect_list++;
       }
@@ -4203,6 +4184,24 @@ linux_nat_do_thread_registers (bfd *obfd
      the new support, the code below should be deleted.  */
   else
     {
+      gdb_gregset_t gregs;
+      gdb_fpregset_t fpregs;
+
+      if (core_regset_p
+	  && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+							 sizeof (gregs))) != NULL
+	  && regset->collect_regset != NULL)
+	regset->collect_regset (regset, regcache, -1,
+				&gregs, sizeof (gregs));
+      else
+	fill_gregset (regcache, &gregs, -1);
+
+      note_data = (char *) elfcore_write_prstatus (obfd,
+						   note_data,
+						   note_size,
+						   lwp,
+						   stop_signal, &gregs);
+
       if (core_regset_p
           && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
 							 sizeof (fpregs))) != NULL
Index: gdb/ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.121
diff -u -p -r1.121 ppc-linux-tdep.c
--- gdb/ppc-linux-tdep.c	15 Apr 2010 20:19:24 -0000	1.121
+++ gdb/ppc-linux-tdep.c	6 Jul 2010 20:24:46 -0000
@@ -516,7 +516,7 @@ ppc64_standard_linkage1_target (struct f
 
 static struct core_regset_section ppc_linux_vsx_regset_sections[] =
 {
-  { ".reg", 268, "general-purpose" },
+  { ".reg", 48 * 4, "general-purpose" },
   { ".reg2", 264, "floating-point" },
   { ".reg-ppc-vmx", 544, "ppc Altivec" },
   { ".reg-ppc-vsx", 256, "POWER7 VSX" },
@@ -525,7 +525,7 @@ static struct core_regset_section ppc_li
 
 static struct core_regset_section ppc_linux_vmx_regset_sections[] =
 {
-  { ".reg", 268, "general-purpose" },
+  { ".reg", 48 * 4, "general-purpose" },
   { ".reg2", 264, "floating-point" },
   { ".reg-ppc-vmx", 544, "ppc Altivec" },
   { NULL, 0}
@@ -533,7 +533,31 @@ static struct core_regset_section ppc_li
 
 static struct core_regset_section ppc_linux_fp_regset_sections[] =
 {
-  { ".reg", 268, "general-purpose" },
+  { ".reg", 48 * 4, "general-purpose" },
+  { ".reg2", 264, "floating-point" },
+  { NULL, 0}
+};
+
+static struct core_regset_section ppc64_linux_vsx_regset_sections[] =
+{
+  { ".reg", 48 * 8, "general-purpose" },
+  { ".reg2", 264, "floating-point" },
+  { ".reg-ppc-vmx", 544, "ppc Altivec" },
+  { ".reg-ppc-vsx", 256, "POWER7 VSX" },
+  { NULL, 0}
+};
+
+static struct core_regset_section ppc64_linux_vmx_regset_sections[] =
+{
+  { ".reg", 48 * 8, "general-purpose" },
+  { ".reg2", 264, "floating-point" },
+  { ".reg-ppc-vmx", 544, "ppc Altivec" },
+  { NULL, 0}
+};
+
+static struct core_regset_section ppc64_linux_fp_regset_sections[] =
+{
+  { ".reg", 48 * 8, "general-purpose" },
   { ".reg2", 264, "floating-point" },
   { NULL, 0}
 };
@@ -1507,6 +1531,19 @@ ppc_linux_init_abi (struct gdbarch_info 
 	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpcle");
       else
 	set_gdbarch_gcore_bfd_target (gdbarch, "elf32-powerpc");
+
+      /* Supported register sections.  */
+      if (tdesc_find_feature (info.target_desc,
+			      "org.gnu.gdb.power.vsx"))
+	set_gdbarch_core_regset_sections (gdbarch,
+					  ppc_linux_vsx_regset_sections);
+      else if (tdesc_find_feature (info.target_desc,
+			       "org.gnu.gdb.power.altivec"))
+	set_gdbarch_core_regset_sections (gdbarch,
+					  ppc_linux_vmx_regset_sections);
+      else
+	set_gdbarch_core_regset_sections (gdbarch,
+					  ppc_linux_fp_regset_sections);
     }
   
   if (tdep->wordsize == 8)
@@ -1533,20 +1570,23 @@ ppc_linux_init_abi (struct gdbarch_info 
 	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpcle");
       else
 	set_gdbarch_gcore_bfd_target (gdbarch, "elf64-powerpc");
+
+      /* Supported register sections.  */
+      if (tdesc_find_feature (info.target_desc,
+			      "org.gnu.gdb.power.vsx"))
+	set_gdbarch_core_regset_sections (gdbarch,
+					  ppc64_linux_vsx_regset_sections);
+      else if (tdesc_find_feature (info.target_desc,
+			       "org.gnu.gdb.power.altivec"))
+	set_gdbarch_core_regset_sections (gdbarch,
+					  ppc64_linux_vmx_regset_sections);
+      else
+	set_gdbarch_core_regset_sections (gdbarch,
+					  ppc64_linux_fp_regset_sections);
     }
   set_gdbarch_regset_from_core_section (gdbarch, ppc_linux_regset_from_core_section);
   set_gdbarch_core_read_description (gdbarch, ppc_linux_core_read_description);
 
-  /* Supported register sections.  */
-  if (tdesc_find_feature (info.target_desc,
-			  "org.gnu.gdb.power.vsx"))
-    set_gdbarch_core_regset_sections (gdbarch, ppc_linux_vsx_regset_sections);
-  else if (tdesc_find_feature (info.target_desc,
-			       "org.gnu.gdb.power.altivec"))
-    set_gdbarch_core_regset_sections (gdbarch, ppc_linux_vmx_regset_sections);
-  else
-    set_gdbarch_core_regset_sections (gdbarch, ppc_linux_fp_regset_sections);
-
   /* Enable TLS support.  */
   set_gdbarch_fetch_tls_load_module_address (gdbarch,
                                              svr4_fetch_objfile_link_map);


-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-06 20:48       ` Ulrich Weigand
@ 2010-07-06 21:29         ` Mark Kettenis
  2010-07-07 12:30           ` Ulrich Weigand
  0 siblings, 1 reply; 18+ messages in thread
From: Mark Kettenis @ 2010-07-06 21:29 UTC (permalink / raw)
  To: uweigand; +Cc: jan.kratochvil, Jon.Zhou, gdb

> Date: Tue, 6 Jul 2010 22:48:44 +0200 (CEST)
> From: "Ulrich Weigand" <uweigand@de.ibm.com>
> 
> Mark Kettenis wrote:
> 
> > Fixing the code in linux-nat.c is a bit nasty:
> > 
> > * The definition of the 32-bit version of gdb_gregset_t isn't readily
> >   available on 64-bit systems.
> > 
> > * The code is used on all Linux platforms and only a few of them are
> >   bi-arch.
> 
> This was really supposed to be fixed by the gdbarch_core_regset_sections
> mechanism, which provides the names and sizes of all register sets
> expected in a core file for the current architecture.
> 
> However, it seems that this mechanism isn't currently used for .reg
> itself, only for the other sections.  While it is true that .reg needs
> to be handled somewhat specially, it should still be possible to get
> its size from gdbarch_core_regset_sections, and thus avoid the need
> to use the gdb_gregset_t type.
> 
> Unfortunately, it also turned out that the section sizes provided for
> .reg in those targets that have gdbarch_core_regset_sections, while
> currently unused, were also nearly all wrong ...
> 
> The following patch fixes those sizes, and changes linux-nat.c to
> use them.
> 
> Tested on powerpc64-linux (-m64 / -m32), amd64-linux (-m64 / -m32),
> and i386-linux with no regressions.  In fact, it appears to fix all
> pre-existing gcore-related failures on amd64 -m32 ...
> 
> Thoughts?

Although I don't feel qualified to judge the powerpc bits, this makes
quite a bit of sense to me.  And yes, the value for amd64-linux is
obviously wrong.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-06 21:29         ` Mark Kettenis
@ 2010-07-07 12:30           ` Ulrich Weigand
  2010-07-08  2:35             ` Jon Zhou
  2010-07-08  4:47             ` H.J. Lu
  0 siblings, 2 replies; 18+ messages in thread
From: Ulrich Weigand @ 2010-07-07 12:30 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: jan.kratochvil, Jon.Zhou, gdb, gdb-patches

Mark Kettenis wrote:
> > Date: Tue, 6 Jul 2010 22:48:44 +0200 (CEST)
> > From: "Ulrich Weigand" <uweigand@de.ibm.com>
> > 
> > Unfortunately, it also turned out that the section sizes provided for
> > .reg in those targets that have gdbarch_core_regset_sections, while
> > currently unused, were also nearly all wrong ...
> > 
> > The following patch fixes those sizes, and changes linux-nat.c to
> > use them.

> Although I don't feel qualified to judge the powerpc bits, this makes
> quite a bit of sense to me.  And yes, the value for amd64-linux is
> obviously wrong.

OK, thanks!

I've checked the patch in now.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Examining copied stack contents
  2010-07-05 18:50 ` Examining copied stack contents Petr Hluzín
  2010-07-05 20:18   ` Martin Schröder
@ 2010-07-07 17:29   ` Martin Schröder
  1 sibling, 0 replies; 18+ messages in thread
From: Martin Schröder @ 2010-07-07 17:29 UTC (permalink / raw)
  To: Petr Hluzín; +Cc: brobecker, gdb

Petr Hluzín wrote:
> On 3 July 2010 12:46, Martin Schröder <gschroeder@onlinehome.de>
> wrote:
>
> In general a debugger needs at least a stack pointer and an
> instruction pointer to get a backtrace. If the function containing the
> IP uses a frame pointer (a debugger should be able to tell you that)
> then debugger needs to know the FP. Which register contains the FP
> depends on the prologue type chosen by compiler (on x86 it is always
> EBP). Command "info frame <address>" may assume IP is pointed to by
> SP. So there are at least 2 arguments (FP+SP) to be provided on any
> arch.
>
> Therefore I suspect "info frame <address>" is not general enough to be
> used in your case.

Hello everyone; and thanks to Petr and Joel.

The above comment was exactly what I needed to find a working solution 
for my problem, at least as long as GDB uses Dwarf2 frame unwinding (but 
it *probably* should work with the other unwinders, too).


Due to the content of the stack being an unaltered copy, it's of course 
impossible for GDB to properly unwind it at its current location. Thus, 
you have to copy it back to its original position. But since you almost 
always want to continue your program properly later on, your first step 
has to be to save the part of the stack that's going to be overwritten.

If you assume that the convenience variable "$base" is the original 
address of the stack, "$length" its length and "$copyPos" the address of 
the copy, you have to execute the following commands:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
gdb> set $stack = malloc($length)
gdb> p memcpy($stack, $base, $length);
gdb> p memcpy($base, $copyPos, $length);
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Of course, you should check if malloc returns something other than 0. 
But for brevity's sake, I won't write down the sanity checks.

In any case, after you've backed-up the current stack and copied over 
the old stack, you have to set the $epb and $eip registers to allow GDB 
to understand the stack. Both should be stored within the jmp_buf struct 
that's created by the setjmp() statement.

Unfortunately, due to security reasons, glibc masks the stack pointer 
register (which is not needed by GDB, strangely enough) and the eip 
register on Linux. Their actual values are xor-ed with a fixed pattern 
and then rotated by 9 bits to the left [1]. After undoing that, you can 
get the eip and all that remains to do is to fetch the ebp frame 
pointer.

In my case that's simple, because due to the way the stack is copied, 
the ebp register is always 9 bytes less than the "base" variable. 
Otherwise, you have to dig around where the ebp is stored inside the 
jmp_buf or get it from somewhere else (like I did).

Anyway, after you have the ebp and eip values, simply back them up and 
set them with the following commands:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
gdb> set $ebpsave = $ebp
gdb> set $eipsave = $eip
gdb> p $ebp = 0x<Hexadecimal-EBP-Content>
gdb> p $eip = 0x<Hexadecimal-EIP-Content>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Now, you can get a full backtrace and explore the frame details.

If you later intend to continue execution, just reset your changes:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
gdb> p $ebp = $ebpsave
gdb> p $eip = $eipsave
gdb> p memcpy($base, $stack, $length)
gdb> p free($stack)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


That's it. A bit crude since you can't exactly "just" look at it, need 
to learn the correct values of ebp and eip and it only works like that 
on x86, but hey, at least it *does* work. :)



Thanks again for you help!
    Martin Schröder.


[1] - http://cseweb.ucsd.edu/~hovav/dist/noret.pdf Page 14

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: support biarch gcore?
  2010-07-07 12:30           ` Ulrich Weigand
@ 2010-07-08  2:35             ` Jon Zhou
  2010-07-08 11:17               ` Ulrich Weigand
  2010-07-08  4:47             ` H.J. Lu
  1 sibling, 1 reply; 18+ messages in thread
From: Jon Zhou @ 2010-07-08  2:35 UTC (permalink / raw)
  To: Ulrich Weigand, Mark Kettenis; +Cc: jan.kratochvil, gdb, gdb-patches

One more question

The patch is enable gdb to read the coredump generated by gcore
Or enable gcore to generate a readable coredump
Or both?

Thanks
jon

-----Original Message-----
From: Ulrich Weigand [mailto:uweigand@de.ibm.com] 
Sent: Wednesday, July 07, 2010 8:31 PM
To: Mark Kettenis
Cc: jan.kratochvil@redhat.com; Jon Zhou; gdb@sourceware.org; gdb-patches@sourceware.org
Subject: Re: support biarch gcore?

Mark Kettenis wrote:
> > Date: Tue, 6 Jul 2010 22:48:44 +0200 (CEST)
> > From: "Ulrich Weigand" <uweigand@de.ibm.com>
> > 
> > Unfortunately, it also turned out that the section sizes provided for
> > .reg in those targets that have gdbarch_core_regset_sections, while
> > currently unused, were also nearly all wrong ...
> > 
> > The following patch fixes those sizes, and changes linux-nat.c to
> > use them.

> Although I don't feel qualified to judge the powerpc bits, this makes
> quite a bit of sense to me.  And yes, the value for amd64-linux is
> obviously wrong.

OK, thanks!

I've checked the patch in now.

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-07 12:30           ` Ulrich Weigand
  2010-07-08  2:35             ` Jon Zhou
@ 2010-07-08  4:47             ` H.J. Lu
  2010-07-08  5:05               ` H.J. Lu
  1 sibling, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2010-07-08  4:47 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Mark Kettenis, jan.kratochvil, Jon.Zhou, gdb, gdb-patches

On Wed, Jul 7, 2010 at 5:30 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> Mark Kettenis wrote:
>> > Date: Tue, 6 Jul 2010 22:48:44 +0200 (CEST)
>> > From: "Ulrich Weigand" <uweigand@de.ibm.com>
>> >
>> > Unfortunately, it also turned out that the section sizes provided for
>> > .reg in those targets that have gdbarch_core_regset_sections, while
>> > currently unused, were also nearly all wrong ...
>> >
>> > The following patch fixes those sizes, and changes linux-nat.c to
>> > use them.
>
>> Although I don't feel qualified to judge the powerpc bits, this makes
>> quite a bit of sense to me.  And yes, the value for amd64-linux is
>> obviously wrong.
>
> OK, thanks!
>
> I've checked the patch in now.
>

Does this fix

http://sourceware.org/bugzilla/show_bug.cgi?id=11467

You can verify it with the testcase in

http://sourceware.org/ml/gdb-patches/2010-04/msg00425.html



-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-08  4:47             ` H.J. Lu
@ 2010-07-08  5:05               ` H.J. Lu
  2010-07-08 11:15                 ` Ulrich Weigand
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2010-07-08  5:05 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Mark Kettenis, jan.kratochvil, Jon.Zhou, gdb, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1107 bytes --]

On Wed, Jul 7, 2010 at 9:47 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Jul 7, 2010 at 5:30 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
>> Mark Kettenis wrote:
>>> > Date: Tue, 6 Jul 2010 22:48:44 +0200 (CEST)
>>> > From: "Ulrich Weigand" <uweigand@de.ibm.com>
>>> >
>>> > Unfortunately, it also turned out that the section sizes provided for
>>> > .reg in those targets that have gdbarch_core_regset_sections, while
>>> > currently unused, were also nearly all wrong ...
>>> >
>>> > The following patch fixes those sizes, and changes linux-nat.c to
>>> > use them.
>>
>>> Although I don't feel qualified to judge the powerpc bits, this makes
>>> quite a bit of sense to me.  And yes, the value for amd64-linux is
>>> obviously wrong.
>>
>> OK, thanks!
>>
>> I've checked the patch in now.
>>
>
> Does this fix
>
> http://sourceware.org/bugzilla/show_bug.cgi?id=11467
>

It works.  Here is a patch to add a testcase.  OK to install?

Thanks.


-- 
H.J.
--
2010-07-07  H.J. Lu  <hongjiu.lu@intel.com>

	PR corefiles/11467
	* gdb.arch/amd64-gcore32.exp: New.

[-- Attachment #2: gdb-32bit-8.patch --]
[-- Type: text/x-csrc, Size: 7530 bytes --]

2010-07-07  H.J. Lu  <hongjiu.lu@intel.com>

	PR corefiles/11467
	* gdb.arch/amd64-gcore32.exp: New.

diff --git a/gdb/testsuite/gdb.arch/amd64-gcore32.exp b/gdb/testsuite/gdb.arch/amd64-gcore32.exp
new file mode 100644
index 0000000..66f733d
--- /dev/null
+++ b/gdb/testsuite/gdb.arch/amd64-gcore32.exp
@@ -0,0 +1,227 @@
+# Copyright 2010
+# Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+	strace $tracelevel
+}
+
+if { ![istarget x86_64-*-linux* ] } {
+    verbose "Skipping amd64-linux 32bit gcore tests."
+    return
+}
+
+set testfile "amd64-gcore32"
+set srcfile  gcore.c
+set binfile  ${objdir}/${subdir}/${testfile}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "additional_flags=-m32"]] != "" } {
+     untested amd64-gcore32.exp
+     return -1
+}
+
+# Start with a fresh gdb.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+# Does this gdb support gcore?
+send_gdb "help gcore\n"
+gdb_expect {
+    -re "Undefined command: .gcore.*$gdb_prompt $" {
+	# gcore command not supported -- nothing to test here.
+	unsupported "gdb does not support gcore on this target"
+	return -1;
+    }
+    -re "Save a core file .*$gdb_prompt $" {
+	pass "help gcore"
+    }
+    -re ".*$gdb_prompt $" {
+	fail "help gcore"
+    }
+    timeout {
+	fail "help gcore (timeout)"
+    }
+}
+
+if { ! [ runto_main ] } then {
+    untested amd64-gcore32.exp
+    return -1
+}
+
+proc capture_command_output { command prefix } {
+    global gdb_prompt
+    global expect_out
+
+    set output_string ""
+    gdb_test_multiple "$command" "capture_command_output for $command" {
+	-re "${command}\[\r\n\]+${prefix}(.*)\[\r\n\]+$gdb_prompt $" {
+	    set output_string $expect_out(1,string)
+	}
+    }
+    return $output_string
+}
+
+gdb_test "break terminal_func" "Breakpoint .* at .*${srcfile}, line .*" \
+	"set breakpoint at terminal_func"
+
+gdb_test "continue" "Breakpoint .* terminal_func.*" \
+	"continue to terminal_func"
+
+set print_prefix ".\[0123456789\]* = "
+
+set pre_corefile_backtrace [capture_command_output "backtrace" ""]
+set pre_corefile_regs [capture_command_output "info registers" ""]
+set pre_corefile_allregs [capture_command_output "info all-reg" ""]
+set pre_corefile_static_array \
+	[capture_command_output "print static_array" "$print_prefix"]
+set pre_corefile_uninit_array \
+	[capture_command_output "print un_initialized_array" "$print_prefix"]
+set pre_corefile_heap_string \
+	[capture_command_output "print heap_string" "$print_prefix"]
+set pre_corefile_local_array \
+	[capture_command_output "print array_func::local_array" "$print_prefix"]
+set pre_corefile_extern_array \
+	[capture_command_output "print extern_array" "$print_prefix"]
+
+set escapedfilename [string_to_regexp ${objdir}/${subdir}/gcore.test]
+
+set core_supported 0
+gdb_test_multiple "gcore ${objdir}/${subdir}/gcore.test" \
+	"save a corefile" \
+{
+  -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" {
+    pass "save a corefile"
+    global core_supported
+    set core_supported 1
+  }
+  -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" {
+    unsupported "save a corefile"
+    global core_supported
+    set core_supported 0
+  }
+}
+
+if {!$core_supported} {
+  return -1
+}
+
+# Now restart gdb and load the corefile.
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+send_gdb "core ${objdir}/${subdir}/gcore.test\n"
+gdb_expect {
+    -re ".* is not a core dump:.*$gdb_prompt $" {
+	fail "re-load generated corefile (bad file format)"
+	# No use proceeding from here.
+	return;	
+    }
+    -re ".*: No such file or directory.*$gdb_prompt $" {
+	fail "re-load generated corefile (file not found)"
+	# No use proceeding from here.
+	return;	
+    }
+    -re ".*Couldn't find .* registers in core file.*$gdb_prompt $" {
+	fail "re-load generated corefile (incomplete note section)"
+    }
+    -re "Core was generated by .*$gdb_prompt $" {
+	pass "re-load generated corefile"
+    }
+    -re ".*$gdb_prompt $" {
+	fail "re-load generated corefile"
+    }
+    timeout {
+	fail "re-load generated corefile (timeout)"
+    }
+}
+
+send_gdb "where\n"
+gdb_expect_list "where in corefile" ".*$gdb_prompt $" {
+    ".*\[\r\n\]+#0 .* terminal_func \\(\\) at "
+    ".*\[\r\n\]+#1 .* array_func \\(\\) at "
+    ".*\[\r\n\]+#2 .* factorial_func \\(value=1\\) at "
+    ".*\[\r\n\]+#3 .* factorial_func \\(value=2\\) at "
+    ".*\[\r\n\]+#4 .* factorial_func \\(value=3\\) at "
+    ".*\[\r\n\]+#5 .* factorial_func \\(value=4\\) at "
+    ".*\[\r\n\]+#6 .* factorial_func \\(value=5\\) at "
+    ".*\[\r\n\]+#7 .* factorial_func \\(value=6\\) at "
+    ".*\[\r\n\]+#8 .* main \\(.*\\) at "
+}
+
+set post_corefile_regs [capture_command_output "info registers" ""]
+if ![string compare $pre_corefile_regs $post_corefile_regs] then {
+    pass "corefile restored general registers"
+} else {
+    fail "corefile restored general registers"
+}
+
+set post_corefile_allregs [capture_command_output "info all-reg" ""]
+if ![string compare $pre_corefile_allregs $post_corefile_allregs] then {
+    pass "corefile restored all registers"
+} else {
+    fail "corefile restored all registers"
+}
+
+set post_corefile_extern_array \
+	[capture_command_output "print extern_array" "$print_prefix"]
+if ![string compare $pre_corefile_extern_array $post_corefile_extern_array]  {
+    pass "corefile restored extern array"
+} else {
+    fail "corefile restored extern array"
+}
+
+set post_corefile_static_array \
+	[capture_command_output "print static_array" "$print_prefix"]
+if ![string compare $pre_corefile_static_array $post_corefile_static_array]  {
+    pass "corefile restored static array"
+} else {
+    fail "corefile restored static array"
+}
+
+set post_corefile_uninit_array \
+	[capture_command_output "print un_initialized_array" "$print_prefix"]
+if ![string compare $pre_corefile_uninit_array $post_corefile_uninit_array]  {
+    pass "corefile restored un-initialized array"
+} else {
+    fail "corefile restored un-initialized array"
+}
+
+set post_corefile_heap_string \
+	[capture_command_output "print heap_string" "$print_prefix"]
+if ![string compare $pre_corefile_heap_string $post_corefile_heap_string]  {
+    pass "corefile restored heap array"
+} else {
+    fail "corefile restored heap array"
+}
+
+set post_corefile_local_array \
+	[capture_command_output "print array_func::local_array" "$print_prefix"]
+if ![string compare $pre_corefile_local_array $post_corefile_local_array]  {
+    pass "corefile restored stack array"
+} else {
+    fail "corefile restored stack array"
+}
+
+set post_corefile_backtrace [capture_command_output "backtrace" ""]
+if ![string compare $pre_corefile_backtrace $post_corefile_backtrace]  {
+    pass "corefile restored backtrace"
+} else {
+    fail "corefile restored backtrace"
+}

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-08  5:05               ` H.J. Lu
@ 2010-07-08 11:15                 ` Ulrich Weigand
  2010-07-08 13:52                   ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Ulrich Weigand @ 2010-07-08 11:15 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Mark Kettenis, jan.kratochvil, Jon.Zhou, gdb, gdb-patches

H.J. Lu wrote:

> It works.  Here is a patch to add a testcase.  OK to install?

Maybe I'm missing something, but it looks like this is an identical
copy of the gcore.exp test, except that the executable is built
with -m32, right?

What does this test check that wouldn't already be checked by running
  make check RUNTESTFLAGS="--target_board='unix/-m32' gcore.exp"
?

Since you should be running the full -m32 testsuite anyway if you care
about the bi-arch debugger, I don't think we want to duplicate this
test case for no real gain ...

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-08  2:35             ` Jon Zhou
@ 2010-07-08 11:17               ` Ulrich Weigand
  0 siblings, 0 replies; 18+ messages in thread
From: Ulrich Weigand @ 2010-07-08 11:17 UTC (permalink / raw)
  To: Jon Zhou; +Cc: Mark Kettenis, jan.kratochvil, gdb, gdb-patches

Jon Zhou wrote:

> One more question
> 
> The patch is enable gdb to read the coredump generated by gcore
> Or enable gcore to generate a readable coredump
> Or both?

The patch fixes the gcore command to generate a coredump in the
proper 32-bit format.

Reading in a 32-bit format coredump did already work correctly
before (e.g. a coredump generated by the kernel).

Bye,
Ulrich

-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  Ulrich.Weigand@de.ibm.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-08 11:15                 ` Ulrich Weigand
@ 2010-07-08 13:52                   ` H.J. Lu
  2010-07-21 22:45                     ` Joseph S. Myers
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2010-07-08 13:52 UTC (permalink / raw)
  To: Ulrich Weigand; +Cc: Mark Kettenis, jan.kratochvil, Jon.Zhou, gdb, gdb-patches

On Thu, Jul 8, 2010 at 4:15 AM, Ulrich Weigand <uweigand@de.ibm.com> wrote:
> H.J. Lu wrote:
>
>> It works.  Here is a patch to add a testcase.  OK to install?
>
> Maybe I'm missing something, but it looks like this is an identical
> copy of the gcore.exp test, except that the executable is built
> with -m32, right?
>
> What does this test check that wouldn't already be checked by running
>  make check RUNTESTFLAGS="--target_board='unix/-m32' gcore.exp"
> ?
>
> Since you should be running the full -m32 testsuite anyway if you care
> about the bi-arch debugger, I don't think we want to duplicate this
> test case for no real gain ...
>

Very good point. There are some arch specific tests which are either
32bit or 64bit. Currently, we check target. It doesn't work -m32. We
need something like

/* { dg-require-effective-target lp64 } */
/* { dg-require-effective-target ilp32 } */


-- 
H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: support biarch gcore?
  2010-07-08 13:52                   ` H.J. Lu
@ 2010-07-21 22:45                     ` Joseph S. Myers
  0 siblings, 0 replies; 18+ messages in thread
From: Joseph S. Myers @ 2010-07-21 22:45 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Ulrich Weigand, Mark Kettenis, jan.kratochvil, Jon.Zhou, gdb,
	gdb-patches

On Thu, 8 Jul 2010, H.J. Lu wrote:

> Very good point. There are some arch specific tests which are either
> 32bit or 64bit. Currently, we check target. It doesn't work -m32. We
> need something like
> 
> /* { dg-require-effective-target lp64 } */
> /* { dg-require-effective-target ilp32 } */

I noted the issue with GDB testcases hardcoding target name tests in a 
previous discussion 
<http://sourceware.org/ml/gdb-patches/2010-03/msg00711.html>, and I think 
adopting GCC-style effective target support would be a good solution.

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2010-07-21 22:45 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-03 10:48 Examining copied stack contents Martin Schröder
2010-07-05  4:54 ` support biarch gcore? Jon Zhou
2010-07-05  7:12   ` Jan Kratochvil
2010-07-05 11:55     ` Mark Kettenis
2010-07-06 20:48       ` Ulrich Weigand
2010-07-06 21:29         ` Mark Kettenis
2010-07-07 12:30           ` Ulrich Weigand
2010-07-08  2:35             ` Jon Zhou
2010-07-08 11:17               ` Ulrich Weigand
2010-07-08  4:47             ` H.J. Lu
2010-07-08  5:05               ` H.J. Lu
2010-07-08 11:15                 ` Ulrich Weigand
2010-07-08 13:52                   ` H.J. Lu
2010-07-21 22:45                     ` Joseph S. Myers
2010-07-05 18:50 ` Examining copied stack contents Petr Hluzín
2010-07-05 20:18   ` Martin Schröder
2010-07-05 20:27     ` Joel Brobecker
2010-07-07 17:29   ` Martin Schröder

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).