Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Michael Snyder <msnyder@vmware.com>
To: Hui Zhu <teawater@gmail.com>
Cc: gdb-patches ml <gdb-patches@sourceware.org>
Subject: Re: [PREC/RFA] Add not_replay to make precord support release memory  	better
Date: Fri, 24 Jul 2009 11:31:00 -0000	[thread overview]
Message-ID: <4A69182D.9090004@vmware.com> (raw)
In-Reply-To: <daef60380907210122t35962b01nf0a393407061a67b@mail.gmail.com>

Hui Zhu wrote:
> Hi,
> 
> Now, in replay reverse mode, if get error with memory entry, it will
> output error.  But it just affect the operation with this part of
> memory.
> So I make a patch to let it set the not_replay in memory entry to 1 in
> this status.  When replay forward mode, this memory entry will not
> really set to memory.

I like the idea.  I like it a lot!
Can this solve the problem with sbrk() too?
(code comments below)

> For example:
> #include <sys/types.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
> #include <errno.h>
> #include <sys/stat.h>
> #include <fcntl.h>
> #include <stdint.h>
> #include <sys/mman.h>
> 
> int
> main(int argc,char *argv[],char *envp[])
> {
> 	char	*buf;
> 
> 	buf = mmap (0, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE |
> MAP_ANONYMOUS, -1, 0);
> 	if (buf == (caddr_t) -1) {
> 		perror ("mmap");
> 		return (-errno);
> 	}
> 
> 	buf[0] = 1;
> 
> 	munmap (buf, 1024);
> 
> 	return (0);
> }
> 
> Before patch:
> gdb ~/gdb/a.out
> 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 "i686-pc-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Setting up the environment for debugging gdb.
> Function "internal_error" not defined.
> Make breakpoint pending on future shared library load? (y or [n])
> [answered N; input not from terminal]
> Function "info_command" not defined.
> Make breakpoint pending on future shared library load? (y or [n])
> [answered N; input not from terminal]
> /home/teawater/gdb/bgdbno/gdb/.gdbinit:8: Error in sourced command file:
> No breakpoint number 0.
> (gdb) start
> During symbol reading, DW_AT_name missing from DW_TAG_base_type.
> Temporary breakpoint 1 at 0x8048425: file 1.c, line 17.
> Starting program: /home/teawater/gdb/a.out
> 
> Temporary breakpoint 1, main (argc=<value optimized out>, argv=<value
> optimized out>, envp=<value optimized out>)
>     at 1.c:17
> 17		buf = mmap (0, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE |
> MAP_ANONYMOUS, -1, 0);
> (gdb) record
> (gdb) n
> During symbol reading, incomplete CFI data; unspecified registers
> (e.g., eax) at 0x8048422.
> 18		if (buf == (caddr_t) -1) {
> (gdb)
> 23		buf[0] = 1;
> (gdb)
> 25		munmap (buf, 1024);
> (gdb)
> The next instruction is syscall munmap.  It will free the memory addr
> = 0xb7fe0000 len = 1024.  It will make record target get error.  Do
> you want to stop the program?([y] or n) n
> 27		return (0);
> (gdb) rc
> Continuing.
> Process record: error reading memory at addr = 0xb7fe0000 len = 1.
> (gdb)
> 
> 
> 
> 
> After patch:
> ./gdb ~/gdb/a.out
> GNU gdb (GDB) 6.8.50.20090721-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 "i686-pc-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>...
> Setting up the environment for debugging gdb.
> Function "internal_error" not defined.
> Make breakpoint pending on future shared library load? (y or [n])
> [answered N; input not from terminal]
> Function "info_command" not defined.
> Make breakpoint pending on future shared library load? (y or [n])
> [answered N; input not from terminal]
> /home/teawater/gdb/bgdbno/gdb/.gdbinit:8: Error in sourced command file:
> No breakpoint number 0.
> (gdb) start
> During symbol reading, DW_AT_name missing from DW_TAG_base_type.
> Temporary breakpoint 1 at 0x8048425: file 1.c, line 17.
> Starting program: /home/teawater/gdb/a.out
> 
> Temporary breakpoint 1, main (argc=<value optimized out>, argv=<value
> optimized out>, envp=<value optimized out>)
>     at 1.c:17
> 17		buf = mmap (0, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE |
> MAP_ANONYMOUS, -1, 0);
> (gdb) record
> (gdb) n
> During symbol reading, incomplete CFI data; unspecified registers
> (e.g., eax) at 0x8048422.
> 18		if (buf == (caddr_t) -1) {
> (gdb)
> 23		buf[0] = 1;
> (gdb)
> 25		munmap (buf, 1024);
> (gdb)
> The next instruction is syscall munmap.  It will free the memory addr
> = 0xb7fe0000 len = 1024.  It will make record target get error.  Do
> you want to stop the program?([y] or n) n
> 27		return (0);
> (gdb) rc
> Continuing.
> 
> No more reverse-execution history.
> main (argc=<value optimized out>, argv=<value optimized out>,
> envp=<value optimized out>) at 1.c:17
> 17		buf = mmap (0, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE |
> MAP_ANONYMOUS, -1, 0);
> (gdb) n
> 18		if (buf == (caddr_t) -1) {
> (gdb)
> 23		buf[0] = 1;
> (gdb)
> 25		munmap (buf, 1024);
> (gdb) rn
> 23		buf[0] = 1;
> 
> 
> 
> Please help me review it.
> 
> Thanks,
> Hui
> 
> 2009-07-21  Hui Zhu  <teawater@gmail.com>
> 	
> 	* record.c (record_mem_entry): Add not_replay.  If this the
> 	memory entry doesn't replay, it will set to 1.
> 	(record_arch_list_add_mem): Initialize not_replay to 0.
> 	(record_wait): In replay reverse mode, if get error with
> 	memory entry, not output error, just set not_replay to 1.
> 	In replay forward mode, if not_replay is set, don't set
> 	memory entry to memory.

A changelog entry doesn't need to explain so much.
This much explanation belongs in comments in the code.

Change log entries explain more "what was changed",
and not so much "why".

This should say something like:

	* record.c (record_mem_entry): New field 'not_replay'.
	(record_arch_list_add_mem): Initialize not_replay to 0.
	(record_wait): Set 'not_replay' flag if target memory
	not readable.  Don't try to change target memory if
	'not_replay' is set.



> ---
>  record.c |   75 ++++++++++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 50 insertions(+), 25 deletions(-)
> 
> --- a/record.c
> +++ b/record.c
> @@ -51,6 +51,7 @@ struct record_mem_entry
>  {
>    CORE_ADDR addr;
>    int len;
> +  int not_replay;

This needs a more descriptive name (and some comments!)

How about something like:

     /* Set this flag if target memory for this entry
        can no longer be accessed.  */
     int mem_entry_not_accessible;

>    gdb_byte *val;
>  };
> 
> @@ -275,6 +276,7 @@ record_arch_list_add_mem (CORE_ADDR addr
>    rec->type = record_mem;
>    rec->u.mem.addr = addr;
>    rec->u.mem.len = len;
> +  rec->u.mem.not_replay = 0;
> 
>    if (target_read_memory (addr, rec->u.mem.val, len))
>      {
> @@ -727,32 +729,55 @@ record_wait (struct target_ops *ops,
>  	  else if (record_list->type == record_mem)
>  	    {
>  	      /* mem */
> -	      gdb_byte *mem = alloca (record_list->u.mem.len);
> -	      if (record_debug > 1)
> -		fprintf_unfiltered (gdb_stdlog,
> -				    "Process record: record_mem %s to "
> -				    "inferior addr = %s len = %d.\n",
> -				    host_address_to_string (record_list),
> -				    paddress (gdbarch, record_list->u.mem.addr),
> -				    record_list->u.mem.len);
> -
> -	      if (target_read_memory
> -		  (record_list->u.mem.addr, mem, record_list->u.mem.len))
> -		error (_("Process record: error reading memory at "
> -			 "addr = %s len = %d."),
> -		       paddress (gdbarch, record_list->u.mem.addr),
> -		       record_list->u.mem.len);
> -
> -	      if (target_write_memory
> -		  (record_list->u.mem.addr, record_list->u.mem.val,
> -		   record_list->u.mem.len))
> -		error (_
> -		       ("Process record: error writing memory at "
> -			"addr = %s len = %d."),
> -		       paddress (gdbarch, record_list->u.mem.addr),
> -		       record_list->u.mem.len);
> +	      if (record_list->u.mem.not_replay
> +		  && execution_direction != EXEC_REVERSE)
> +		record_list->u.mem.not_replay = 0;

First of all, a comment to explain what's going on, please.

Now -- if I understand correctly (and please tell if I'm wrong),

1) During the recording "pass", there's no change.
2) During the reverse-replay pass, if the memory is
not readable or writable, we will set this flag to TRUE.
3) Finally, during the forward-replay pass, if the flag
has previously been set to TRUE, we will skip this entry
(and set the flag to FALSE.)

So my question is -- is there any reason to set it to FALSE here?
Is there any way that the memory can ever become readable again?

Seems to me, once it is set TRUE, we might as well just leave it TRUE.
Am I right?

> +	      else
> +		{
> +		  gdb_byte *mem = alloca (record_list->u.mem.len);
> +		  if (record_debug > 1)
> +		    fprintf_unfiltered (gdb_stdlog,
> +				        "Process record: record_mem %s to "
> +				        "inferior addr = %s len = %d.\n",
> +				        host_address_to_string (record_list),
> +				        paddress (gdbarch,
> +					          record_list->u.mem.addr),
> +				        record_list->u.mem.len);
> 
> -	      memcpy (record_list->u.mem.val, mem, record_list->u.mem.len);
> +		  if (target_read_memory (record_list->u.mem.addr, mem,
> +		                          record_list->u.mem.len))
> +	            {
> +		      if (execution_direction != EXEC_REVERSE)
> +		        error (_("Process record: error reading memory at "
> +			         "addr = %s len = %d."),
> +		               paddress (gdbarch, record_list->u.mem.addr),
> +		               record_list->u.mem.len);
> +		      else
> +		        record_list->u.mem.not_replay = 1;

A comment to explain what's happening, please.

> +		    }
> +		  else
> +		    {
> +		      if (target_write_memory (record_list->u.mem.addr,
> +			                       record_list->u.mem.val,
> +		                               record_list->u.mem.len))
> +	                {
> +			  if (execution_direction != EXEC_REVERSE)
> +			    error (_("Process record: error writing memory at "
> +			             "addr = %s len = %d."),
> +		                   paddress (gdbarch, record_list->u.mem.addr),
> +		                   record_list->u.mem.len);
> +			  else
> +			    {
> +			      record_list->u.mem.not_replay = 1;

And again, a comment.  This whole section needs more comments,
but let's start with this, before it becomes even more difficult
to understand.

> +			    }
> +			}
> +		      else
> +		        {
> +			  memcpy (record_list->u.mem.val, mem,
> +				  record_list->u.mem.len);
> +			}
> +		    }
> +		}
>  	    }
>  	  else
>  	    {


  reply	other threads:[~2009-07-24  2:17 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-21 15:39 Hui Zhu
2009-07-24 11:31 ` Michael Snyder [this message]
2009-07-24 13:00   ` Hui Zhu
2009-07-25 20:56     ` Michael Snyder
2009-07-27 16:18       ` Hui Zhu
2009-08-01 23:01         ` Michael Snyder
2009-08-02  4:11           ` Hui Zhu
2009-08-03  3:51             ` Hui Zhu
2009-08-03  5:02               ` Michael Snyder
2009-08-03  5:19                 ` Hui Zhu
2009-08-03 17:31                   ` Michael Snyder
2009-08-04  1:50                     ` Hui Zhu
2009-08-04 18:19                       ` Michael Snyder
2009-08-05  1:26                         ` Hui Zhu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A69182D.9090004@vmware.com \
    --to=msnyder@vmware.com \
    --cc=gdb-patches@sourceware.org \
    --cc=teawater@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox