Mirror of the gdb mailing list
 help / color / mirror / Atom feed
* RE: memset (0, 0, 0);
@ 2003-04-08  7:52 Thomas,Stephen
  2003-04-08 13:10 ` Richard Earnshaw
  2003-04-08 17:57 ` Richard Earnshaw
  0 siblings, 2 replies; 15+ messages in thread
From: Thomas,Stephen @ 2003-04-08  7:52 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gdb, newlib, bug-glibc, McGoogan,Sean


Hi Geoff,

Which xmalloc are you referring to? The xmalloc in this case is a gdb internal function, defined in gdb/utils.c:

PTR xmalloc (size_t size)
{
  return xmmalloc (NULL, size);
}

And xmmalloc is:

void * xmmalloc (void *md, size_t size)
{
  void *val;

  if (size == 0)
    {
      val = NULL;
    }
  else
    {
      val = mmalloc (md, size);
      if (val == NULL)
	nomem (size);
    }
  return (val);
}

So size=0 does indeed return NULL. Also, I have single stepped this code to verify that this is actually what happens.

Steve Thomas
SuperH (UK) Ltd.

-----Original Message-----
From: Geoff Keating [mailto:geoffk@geoffk.org] 
Sent: 07 April 2003 18:18
To: Thomas,Stephen
Cc: gdb@sources.redhat.com; newlib@sources.redhat.com; bug-glibc@gnu.org; McGoogan,Sean
Subject: Re: memset (0, 0, 0);


"Thomas,Stephen" <stephen.thomas@superh.com> writes:

> Hi,
> 
> gdb appears to call memset(0,0,0) from build_regcache() in 
> gdb/regcache.c. I can't really claim to understand how this works, but 
> this function appears to get called 3 times during gdb initialization:
> 
>   static void build_regcache (void)
>   {
>     ...
>     int sizeof_register_valid;
>     ...
>     sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (*register_valid));
>     register_valid = xmalloc (sizeof_register_valid);
>     memset (register_valid, 0, sizeof_register_valid);
>   }
> 
> On the 1st time of calling, none of the gdbarch stuff is set up, so 
> NUM_REGS = NUM_PSEUDO_REGS = 0. So xmalloc gets called with size=0. 
> That returns 0 as the 'address', which gets passed to memset. I guess 
> this just works OK on other architectures (it does on x86 anyway).
> 
> Easy enough to fix I suppose, but is that really the point?

xmalloc is never supposed to return 0, and in fact, there's code to prevent it:

  if (size == 0)
    size = 1;
  newmem = malloc (size);
  if (!newmem)
    xmalloc_failed (size);
  return (newmem);

xmalloc_failed finishes with

  xexit (1);

so xmalloc should never return NULL.

-- 
- Geoffrey Keating <geoffk@geoffk.org>


^ permalink raw reply	[flat|nested] 15+ messages in thread
* RE: memset (0, 0, 0);
@ 2003-04-07  9:22 Thomas,Stephen
  2003-04-07 13:07 ` Daniel Jacobowitz
  2003-04-07 17:18 ` Geoff Keating
  0 siblings, 2 replies; 15+ messages in thread
From: Thomas,Stephen @ 2003-04-07  9:22 UTC (permalink / raw)
  To: Andrew Cagney, Rennecke,Joern; +Cc: gdb, newlib, bug-glibc, McGoogan,Sean

Hi,

gdb appears to call memset(0,0,0) from build_regcache() in gdb/regcache.c. I can't really claim to understand how this works, but this function appears to get called 3 times during gdb initialization:

  static void build_regcache (void)
  {
    ...
    int sizeof_register_valid;
    ...
    sizeof_register_valid = ((NUM_REGS + NUM_PSEUDO_REGS) * sizeof (*register_valid));
    register_valid = xmalloc (sizeof_register_valid);
    memset (register_valid, 0, sizeof_register_valid);
  }

On the 1st time of calling, none of the gdbarch stuff is set up, so NUM_REGS = NUM_PSEUDO_REGS = 0. So xmalloc gets called with size=0. That returns 0 as the 'address', which gets passed to memset. I guess this just works OK on other architectures (it does on x86 anyway).

Easy enough to fix I suppose, but is that really the point?

Steve Thomas
SuperH (UK) Ltd.

-----Original Message-----
From: Andrew Cagney [mailto:ac131313@redhat.com] 
Sent: 04 April 2003 16:17
To: Rennecke,Joern
Cc: gdb@sources.redhat.com; newlib@sources.redhat.com; bug-glibc@gnu.org; Thomas,Stephen; McGoogan,Sean
Subject: Re: memset (0, 0, 0);


> This conflicts with gdb usage of memset (0, 0, 0); in some places. 
> There are three practical questions here:
> - should gdb use this idiom?
> - should all target-specific variants of newlib's memset implement it?
> - should all target-specific variants of glibc's memset implement it?

I'm not sure why you're refering to GDB here.  GDB assumes ISO C and 
hence should never use memset in ways that violate the ISO C spec.  If 
it is, then someone gets to fix it.

Andrew



^ permalink raw reply	[flat|nested] 15+ messages in thread
* Re: memset (0, 0, 0);
@ 2003-04-04 16:12 Petr Vandrovec
  2003-04-04 21:36 ` Andreas Schwab
  0 siblings, 1 reply; 15+ messages in thread
From: Petr Vandrovec @ 2003-04-04 16:12 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: sean.mcgoogan, bug-glibc, stephen.thomas, newlib, gdb

On  4 Apr 03 at 17:21, Andreas Schwab wrote:
> Joern Rennecke <joern.rennecke@superh.com> writes:
> 
> |> So, as i understand this, this means that the first argument of memset
> |> must point to an object, which contains at least one (the first)
> |> character.  Passing a NULL pointer, or any other address which is
> |> outside the address space of the program, invokes undefined behaviour.

But it is completely safe to call memset with unaligned pointer. Your
word read will do bad things in such situation (either you'll read memory
before object, or you'll read memory after object - first can cause
unexpected behavior, second can cause crash).

And it must not modify area outside of specified range, so please make sure
that

volatile unsigned int ptr;
memset(&ptr, 0, 0);

does not do any write at &ptr. I think that even reading from &ptr is
unexpected side effect...

BTW, all functions I know handle NULL, 0 without crash - being it
read, write, recvfrom (for both data & address), or current 
implementation of memset, memcpy.
                                            Petr Vandrovec
                                            


^ permalink raw reply	[flat|nested] 15+ messages in thread
* memset (0, 0, 0);
@ 2003-04-04 14:54 Joern Rennecke
  2003-04-04 15:04 ` Daniel Jacobowitz
                   ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Joern Rennecke @ 2003-04-04 14:54 UTC (permalink / raw)
  To: gdb, newlib, bug-glibc; +Cc: stephen.thomas, sean.mcgoogan

On some processors, memset can be implemented more efficiently
when you always read - and possibly also write back - the first
memory word contained partially or in whole in the to-be-modified
object

This conflicts with gdb usage of memset (0, 0, 0); in some places.
There are three practical questions here:
- should gdb use this idiom?
- should all target-specific variants of newlib's memset implement it?
- should all target-specific variants of glibc's memset implement it?

My understanding of the standard is that memset with an unmapped
destination address always invokes undefined behavior.  It says:

   3.14: object:
    ...  Except for bit-fields, objects are composed of contigous
    sequences of one or more bytes, ...
   7.1.7: Use of library functions
    Each of the following statements apply unless explicitly stated
    otherwise in the detailed descriptions that follow.  If an argument
    has an invalid value (such as a value outside the domain of the
    function, or a pointer outside the address space of the program, or
    a null pointer), the behaviour is undefined.  If a function argument
    is described as being an array, the pointer actually passed to the
    function shall have a value such that all address computations and
    accesses to objects (that would be valid if the pointer did point to
    the first element of such an array) are in fact valid. ...
   7.11.1 String function conventions
    The header <string.h> declares one type and several functions, and
    defines one macro useful for manipulating arrays of character type
    and other objects treated as arrays of character type.  ...  in all
    cases a char * or a void * argument points to the initial (lowest
    addressed) character of the array. ...
   7.11.6.1 The memset function
    ... void *memset (void *s, int c, size_t n);  ...
    The memset function copies the value of c (converted to unsigned
    char) into each of the first n characters of the object pointed to
    by s.  ...

So, as i understand this, this means that the first argument of memset
must point to an object, which contains at least one (the first)
character.  Passing a NULL pointer, or any other address which is
outside the address space of the program, invokes undefined behaviour.

-- 
--------------------------
SuperH (UK) Ltd.
2410 Aztec West / Almondsbury / BRISTOL / BS32 4QX
T:+44 1454 465658


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

end of thread, other threads:[~2003-04-08 20:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-08  7:52 memset (0, 0, 0); Thomas,Stephen
2003-04-08 13:10 ` Richard Earnshaw
2003-04-08 13:26   ` Daniel Jacobowitz
2003-04-08 16:40     ` Richard Earnshaw
2003-04-08 20:51     ` Andrew Cagney
2003-04-08 17:57 ` Richard Earnshaw
  -- strict thread matches above, loose matches on Subject: below --
2003-04-07  9:22 Thomas,Stephen
2003-04-07 13:07 ` Daniel Jacobowitz
2003-04-07 17:18 ` Geoff Keating
2003-04-04 16:12 Petr Vandrovec
2003-04-04 21:36 ` Andreas Schwab
2003-04-04 14:54 Joern Rennecke
2003-04-04 15:04 ` Daniel Jacobowitz
2003-04-04 15:16 ` Andrew Cagney
2003-04-04 15:21 ` Andreas Schwab

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox