public inbox for gdb@sourceware.org
 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-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 17:57 ` Richard Earnshaw
  1 sibling, 1 reply; 15+ messages in thread
From: Richard Earnshaw @ 2003-04-08 13:10 UTC (permalink / raw)
  To: Thomas,Stephen
  Cc: Geoff Keating, gdb, newlib, bug-glibc, McGoogan, Sean,
	Richard.Earnshaw, Andrew Cagney

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

It looks as though that implementation of xmalloc doesn't match the 
general specification of xmalloc, which is that xmalloc must *never* 
return NULL (see libiberty/xmalloc.c for the specification).

I'm not sure why gdb is trying to provide its own implementation of these 
functions and not use those in libiberty.  Andrew?

R.

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

* Re: memset (0, 0, 0);
  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
  0 siblings, 2 replies; 15+ messages in thread
From: Daniel Jacobowitz @ 2003-04-08 13:26 UTC (permalink / raw)
  To: Richard.Earnshaw
  Cc: Thomas,Stephen, Geoff Keating, gdb, newlib, bug-glibc, McGoogan,
	Sean, Andrew Cagney

On Tue, Apr 08, 2003 at 10:29:55AM +0100, Richard Earnshaw wrote:
> > 
> > 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.
> 
> It looks as though that implementation of xmalloc doesn't match the 
> general specification of xmalloc, which is that xmalloc must *never* 
> return NULL (see libiberty/xmalloc.c for the specification).
> 
> I'm not sure why gdb is trying to provide its own implementation of these 
> functions and not use those in libiberty.  Andrew?

The ones in libiberty call exit; the ones in gdb call error() and
unwind cleanups.  GDB prefers not to abort when it runs out of memory,
esp. if it can just abort the current operation and reclaim memory.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

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

* Re: memset (0, 0, 0);
  2003-04-08 13:26   ` Daniel Jacobowitz
@ 2003-04-08 16:40     ` Richard Earnshaw
  2003-04-08 20:51     ` Andrew Cagney
  1 sibling, 0 replies; 15+ messages in thread
From: Richard Earnshaw @ 2003-04-08 16:40 UTC (permalink / raw)
  To: Daniel Jacobowitz
  Cc: Richard.Earnshaw, Thomas, Stephen, Geoff Keating, gdb, newlib,
	bug-glibc, McGoogan, Sean, Andrew Cagney

> On Tue, Apr 08, 2003 at 10:29:55AM +0100, Richard Earnshaw wrote:
> > > 
> > > 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.
> > 
> > It looks as though that implementation of xmalloc doesn't match the 
> > general specification of xmalloc, which is that xmalloc must *never* 
> > return NULL (see libiberty/xmalloc.c for the specification).
> > 
> > I'm not sure why gdb is trying to provide its own implementation of these 
> > functions and not use those in libiberty.  Andrew?
> 
> The ones in libiberty call exit; the ones in gdb call error() and
> unwind cleanups.  GDB prefers not to abort when it runs out of memory,
> esp. if it can just abort the current operation and reclaim memory.
>

That's ok, but the bit about returning NULL isn't.  If we want a "malloc" 
routine that always returns NULL on zero size, we shouldn't call it 
xmalloc.

R.

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

* Re: memset (0, 0, 0);
  2003-04-08  7:52 memset (0, 0, 0); Thomas,Stephen
  2003-04-08 13:10 ` Richard Earnshaw
@ 2003-04-08 17:57 ` Richard Earnshaw
  1 sibling, 0 replies; 15+ messages in thread
From: Richard Earnshaw @ 2003-04-08 17:57 UTC (permalink / raw)
  To: Thomas,Stephen
  Cc: Geoff Keating, gdb, McGoogan,  Sean, Richard.Earnshaw, Andrew Cagney

[I've trimmed the cc list, cos the message was bouncing at 
sources.redhat.com]

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

It looks as though that implementation of xmalloc doesn't match the 
general specification of xmalloc, which is that xmalloc must *never* 
return NULL (see libiberty/xmalloc.c for the specification).

I'm not sure why gdb is trying to provide its own implementation of these 
functions and not use those in libiberty.  Andrew?

R.



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

* Re: memset (0, 0, 0);
  2003-04-08 13:26   ` Daniel Jacobowitz
  2003-04-08 16:40     ` Richard Earnshaw
@ 2003-04-08 20:51     ` Andrew Cagney
  1 sibling, 0 replies; 15+ messages in thread
From: Andrew Cagney @ 2003-04-08 20:51 UTC (permalink / raw)
  To: Daniel Jacobowitz
  Cc: Richard.Earnshaw, Thomas,Stephen, Geoff Keating, gdb, McGoogan, Sean

> It looks as though that implementation of xmalloc doesn't match the 
>> general specification of xmalloc, which is that xmalloc must *never* 
>> return NULL (see libiberty/xmalloc.c for the specification).
>> 
>> I'm not sure why gdb is trying to provide its own implementation of these 
>> functions and not use those in libiberty.  Andrew?
> 
> 
> The ones in libiberty call exit; the ones in gdb call error() and
> unwind cleanups.  GDB prefers not to abort when it runs out of memory,
> esp. if it can just abort the current operation and reclaim memory.

The other reason is that, optionally, they need to be routed through to 
  mmalloc() calls.

Anyway, it should be pretty clear that the real problem here is that 
something was lost in the liberty/xmalloc -> gdb/xmalloc translation (I 
suspect that there was a debate way back when and it forgot to take 
liberty's xmalloc's `well defined semantics' into account).

I'll check in a `fix'.

Andrew


^ 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
  1 sibling, 0 replies; 15+ messages in thread
From: Geoff Keating @ 2003-04-07 17:18 UTC (permalink / raw)
  To: Thomas,Stephen; +Cc: gdb, newlib, bug-glibc, McGoogan,Sean

"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
  1 sibling, 0 replies; 15+ messages in thread
From: Daniel Jacobowitz @ 2003-04-07 13:07 UTC (permalink / raw)
  To: Thomas,Stephen
  Cc: Andrew Cagney, Rennecke,Joern, gdb, newlib, bug-glibc, McGoogan,Sean

On Mon, Apr 07, 2003 at 10:22:04AM +0100, Thomas,Stephen wrote:
> 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?

Yes, I think that really is the point.  It's just a bug, IMO.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

^ 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, 0 replies; 15+ messages in thread
From: Andreas Schwab @ 2003-04-04 21:36 UTC (permalink / raw)
  To: Petr Vandrovec; +Cc: sean.mcgoogan, bug-glibc, stephen.thomas, newlib, gdb

"Petr Vandrovec" <VANDROVE@vc.cvut.cz> writes:

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

This is not required.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ 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

* Re: memset (0, 0, 0);
  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
  2 siblings, 0 replies; 15+ messages in thread
From: Andreas Schwab @ 2003-04-04 15:21 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gdb, newlib, bug-glibc, stephen.thomas, sean.mcgoogan

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.

IMHO 7.21.1[#2] gives the definitive answer:

    Where an argument declared as size_t n specifies the length of the
    array for a function, n can have the value zero on a call to that
    function. Unless explicitly stated otherwise in the description of a
    particular function in this subclause, pointer arguments on such a
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    call shall still have valid values, as described in 7.1.4. On such a
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    call, a function that locates a character finds no occurrence, a
    function that compares two character sequences returns zero, and a
    function that copies characters copies zero characters.

7.21.6.1 (The memset function) does not say otherwise.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: memset (0, 0, 0);
  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
  2 siblings, 0 replies; 15+ messages in thread
From: Andrew Cagney @ 2003-04-04 15:16 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gdb, newlib, bug-glibc, stephen.thomas, sean.mcgoogan

> 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 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
  2 siblings, 0 replies; 15+ messages in thread
From: Daniel Jacobowitz @ 2003-04-04 15:04 UTC (permalink / raw)
  To: Joern Rennecke; +Cc: gdb, newlib, bug-glibc, stephen.thomas, sean.mcgoogan

On Fri, Apr 04, 2003 at 03:52:32PM +0100, Joern Rennecke wrote:
> 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?

Where is it that GDB does this?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

^ 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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).