Re: [RFA/RFC Prec] Add Linux AMD64 process record support second version, (AMD64 Linux system call support) 3/3

Hui Zhu
2009-07-20T14:01:49Z

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

Hi Michael,

I still got fail with solib-reverse.exp with this patch.

The attachment is the log.

Thanks,
Hui

On Mon, Jul 20, 2009 at 09:11, Michael Snyder<msnyder@vmware.com> wrote:
> Hui,
>
> Here is an "epilogue unwinder" for the amd64.  Please try it out.
>
> If you update infrun.c now you will see most of your *-record.exp
> testsuites broken by my recent change there.  This will fix them.
>
>
> Thanks,
> Michael
>
>
> --- saveteawater3/amd64-tdep.c  2009-07-19 18:08:56.000000000 -0700
> +++ ./amd64-tdep.c      2009-07-19 18:10:18.000000000 -0700
> @@ -1887,6 +1887,89 @@ static const struct frame_base amd64_fra
>   amd64_frame_base_address
>  };
>
> +/* Normal frames, but in a function epilogue.  */
> +
> +/* The epilogue is defined here as the 'ret' instruction, which will
> +   follow any instruction such as 'leave' or 'pop %ebp' that destroys
> +   the function's stack frame.  */
> +
> +static int
> +amd64_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
> +{
> +  gdb_byte insn;
> +
> +  if (target_read_memory (pc, &insn, 1))
> +    return 0;   /* Can't read memory at pc.  */
> +
> +  if (insn != 0xc3)     /* 'ret' instruction.  */
> +    return 0;
> +
> +  return 1;
> +}
> +
> +static int
> +amd64_epilogue_frame_sniffer (const struct frame_unwind *self,
> +                             struct frame_info *this_frame,
> +                             void **this_prologue_cache)
> +{
> +  if (frame_relative_level (this_frame) == 0)
> +    return amd64_in_function_epilogue_p (get_frame_arch (this_frame),
> +                                        get_frame_pc (this_frame));
> +  else
> +    return 0;
> +}
> +
> +static struct amd64_frame_cache *
> +amd64_epilogue_frame_cache (struct frame_info *this_frame, void
> **this_cache)
> +{
> +  struct gdbarch *gdbarch = get_frame_arch (this_frame);
> +  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
> +  struct amd64_frame_cache *cache;
> +  gdb_byte buf[4];
> +
> +  if (*this_cache)
> +    return *this_cache;
> +
> +  cache = amd64_alloc_frame_cache ();
> +  *this_cache = cache;
> +
> +  /* Cache base will be %esp plus cache->sp_offset (-8).  */
> +  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
> +  cache->base = extract_unsigned_integer (buf, 8,
> +                                         byte_order) + cache->sp_offset;
> +
> +  /* Cache pc will be the frame func.  */
> +  cache->pc = get_frame_pc (this_frame);
> +
> +  /* The saved %esp will be at cache->base plus 16.  */
> +  cache->saved_sp = cache->base + 16;
> +
> +  /* The saved %eip will be at cache->base plus 8.  */
> +  cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8;
> +
> +  return cache;
> +}
> +
> +static void
> +amd64_epilogue_frame_this_id (struct frame_info *this_frame,
> +                             void **this_cache,
> +                             struct frame_id *this_id)
> +{
> +  struct amd64_frame_cache *cache = amd64_epilogue_frame_cache (this_frame,
> +                                                              this_cache);
> +
> +  (*this_id) = frame_id_build (cache->base + 8, cache->pc);
> +}
> +
> +static const struct frame_unwind amd64_epilogue_frame_unwind =
> +{
> +  NORMAL_FRAME,
> +  amd64_epilogue_frame_this_id,
> +  amd64_frame_prev_register,
> +  NULL,
> +  amd64_epilogue_frame_sniffer
> +};
> +
>  static struct frame_id
>  amd64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
>  {
> @@ -2065,6 +2148,12 @@ amd64_init_abi (struct gdbarch_info info
>
>   set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);
>
> +  /* Hook the function epilogue frame unwinder.  This unwinder is
> +     appended to the list first, so that it supercedes the other
> +     unwinders in function epilogues.  */
> +  frame_unwind_prepend_unwinder (gdbarch, &amd64_epilogue_frame_unwind);
> +
> +  /* Hook the prologue-based frame unwinders.  */
>   frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
>   frame_unwind_append_unwinder (gdbarch, &amd64_frame_unwind);
>   frame_base_set_default (gdbarch, &amd64_frame_base);
>
>

[-- Attachment #2: gdb.log --]
[-- Type: text/x-log, Size: 7809 bytes --]

Test Run By teawater on Mon Jul 20 21:57:57 2009
Native configuration is x86_64-unknown-linux-gnu

=== gdb tests ===

Schedule of variations:
precord

Running target precord
Using /usr/share/dejagnu/baseboards/precord.exp as board description file for target.
Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
Using ../src/gdb/testsuite/config/unix.exp as tool-and-target-specific interface file.
Running ../src/gdb/testsuite/gdb.reverse/solib-reverse.exp ...
get_compiler_info: gcc-4-3-3
Executing on host: gcc -fpic -c -g -o /home/teawater/gdb/bt/gdb.reverse/shr2.c.o ../src/gdb/testsuite/gdb.reverse/shr2.c (timeout = 300)
Executing on host: gcc /home/teawater/gdb/bt/gdb.reverse/shr2.c.o -shared -g -lm -o /home/teawater/gdb/bt/gdb.reverse/shr2.sl (timeout = 300)
Executing on host: gcc ../src/gdb/testsuite/gdb.reverse/solib-reverse.c /home/teawater/gdb/bt/gdb.reverse/shr2.sl -g -lm -o /home/teawater/gdb/bt/gdb.reverse/solib-reverse (timeout = 300)
GNU gdb (GDB) 6.8.50.20090720-cvs
Copyright (C) 2009 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/>.
(gdb) set height 0
(gdb) set width 0
(gdb) dir
Reinitialize source path to empty? (y or n) y
Source directories searched: $cdir:$cwd
(gdb) dir ../src/gdb/testsuite/gdb.reverse
Source directories searched: /home/teawater/gdb/bt/../src/gdb/testsuite/gdb.reverse:$cdir:$cwd
(gdb) kill
The program is not being run.
(gdb) file /home/teawater/gdb/bt/gdb.reverse/solib-reverse
Reading symbols from /home/teawater/gdb/bt/gdb.reverse/solib-reverse...done.
(gdb) delete breakpoints
(gdb) info breakpoints
No breakpoints or watchpoints.
(gdb) break main
Breakpoint 1 at 0x4006e4: file ../src/gdb/testsuite/gdb.reverse/solib-reverse.c, line 27.
(gdb) run
Starting program: /home/teawater/gdb/bt/gdb.reverse/solib-reverse

Breakpoint 1, main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) record
(gdb) PASS: gdb.reverse/solib-reverse.exp: Turn on process record
until 41
message 1
message 2
message 3
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:41
41 return 0; /* end part one */
(gdb) PASS: gdb.reverse/solib-reverse.exp: run until end part one
reverse-step
38 sleep (0); /* sleep two */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step third sleep
reverse-step
37 sleep (0); /* sleep one */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step second sleep
reverse-step
35 printf ("message 2\n"); /* printf two */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step first sleep, dynsym resolve
reverse-step
34 printf ("message 1\n"); /* printf one */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step third printf
reverse-step
33 b[0] = 6; b[1] = 9; /* generic statement, end part two */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step second printf
reverse-step
shr2 (x=17) at ../src/gdb/testsuite/gdb.reverse/shr2.c:25
25 }
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step first printf, dynsym resolve
reverse-step
24 return 2*x;
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step generic
until 41
No line 41 in file "../src/gdb/testsuite/gdb.reverse/shr2.c".
(gdb) FAIL: gdb.reverse/solib-reverse.exp: forward to end part one
reverse-next
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:30
30 b[0] = shr2(12); /* begin part two */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next third sleep
reverse-next
28 int b[2] = {5,8};
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next second sleep
reverse-next

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next first sleep, dynsym resolve
reverse-next

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next third printf
reverse-next

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next second printf
reverse-next

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next first printf, dynsym resolve
reverse-next

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next generic
reverse-step

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function one
reverse-step

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function one
reverse-step

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main one
reverse-step

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step into solib function two
reverse-step

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step within solib function two
reverse-step

No more reverse-execution history.
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:27
27 char* cptr = "String 1";
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-step back to main two
until 33
main () at ../src/gdb/testsuite/gdb.reverse/solib-reverse.c:33
33 b[0] = 6; b[1] = 9; /* generic statement, end part two */
(gdb) PASS: gdb.reverse/solib-reverse.exp: run until end part two
reverse-next
30 b[0] = shr2(12); /* begin part two */
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next over solib function one
reverse-next
28 int b[2] = {5,8};
(gdb) FAIL: gdb.reverse/solib-reverse.exp: reverse-next over solib function two
testcase ../src/gdb/testsuite/gdb.reverse/solib-reverse.exp completed in 2 seconds

=== gdb Summary ===

# of expected passes 3
# of unexpected failures 23
Executing on host: gdb -nw -nx --command gdb_cmd (timeout = 300)
GNU gdb (GDB) 6.8.50.20090720-cvs
Copyright (C) 2009 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/>.
/usr/local/bin/gdb version 6.8.50.20090720-cvs -nw -nx

runtest completed at Mon Jul 20 21:57:59 2009