public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: libstdc++/10283: operator new does not return null on some windows systems
@ 2003-04-01 14:29 bangerth
  0 siblings, 0 replies; 3+ messages in thread
From: bangerth @ 2003-04-01 14:29 UTC (permalink / raw)
  To: gcc-bugs, gcc-prs, nobody, zerovalintine

Synopsis: operator new does not return null on some windows systems

State-Changed-From-To: open->closed
State-Changed-By: bangerth
State-Changed-When: Tue Apr  1 14:29:04 2003
State-Changed-Why:
    Not a bug. According to the standard, operator new
    throws an exception when no more memory is available,
    rather than returning NULL. If you want to get NULL
    returned, use new(nothrow), or catch the exception.
    
    W.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=10283


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

* Re: libstdc++/10283: operator new does not return null on some windows systems
@ 2003-04-01  6:16 Tim Prince
  0 siblings, 0 replies; 3+ messages in thread
From: Tim Prince @ 2003-04-01  6:16 UTC (permalink / raw)
  To: nobody; +Cc: gcc-prs

The following reply was made to PR libstdc++/10283; it has been noted by GNATS.

From: Tim Prince <timothyprince@sbcglobal.net>
To: zerovalintine@hotmail.com, gcc-gnats@gcc.gnu.org
Cc:  
Subject: Re: libstdc++/10283: operator new does not return null on some windows systems
Date: Mon, 31 Mar 2003 22:13:49 -0800

 On Monday 31 March 2003 20:34, zerovalintine@hotmail.com wrote:
 > #include <cstdlib>
 > int main(){
 > char * s = new char[1024 * 1024 * 512];
 > if(s != 0) delete[] s;
 > std::system("");
 > return(0);}
 
 You may be ignored when you make a post with so many troll-like elements.  
 Believe it or not, gcc doesn't check what OS you're running on or what 
 run-time you're planning to link in when it optimizes code.  If you consider 
 your problem to be specific to mingw, then it's specific to the way mingw 
 implements its interface to the Windows .dll's.  If you consider it to be the 
 code generated by gcc, you'll be able to see it by looking at the generated 
 asm code.
 
 BTW, your example says "Aborted" when run under linux on my laptop.  libc 
 calls kill().  No way does gcc know that your code should be shortcut by 
 calling kill() directly, if that's what you mean by optimizing.  Nor is 
 libstdc++ calling kill() directly.  I'll check Windows later.
 -- 
 Tim Prince


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

* libstdc++/10283: operator new does not return null on some windows systems
@ 2003-04-01  4:36 zerovalintine
  0 siblings, 0 replies; 3+ messages in thread
From: zerovalintine @ 2003-04-01  4:36 UTC (permalink / raw)
  To: gcc-gnats


>Number:         10283
>Category:       libstdc++
>Synopsis:       operator new does not return null on some windows systems
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Apr 01 04:36:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     zerovalintine@hotmail.com
>Release:        gcc version 3.2 (mingw special 20020817-1)
>Organization:
>Environment:
Windows XP and 2000 - Tested By Me
Windows 98se - Others (I do not have access to test it personally)
>Description:
GCC version 3.2, mingw, apparently overoptimizes, hard to belive, code under some versions of windows. The new operator should return 0, null, when no more memory can be allocated, but windows terminates an offending application before the app. has time. I will try to make that more clear. When allocating more memory than the system currently has, gcc (g++)apparently builds the executable in such a way that it calls constuctors on objects before making sure that the memory is valid. I have examined some examples of assembly produced and finally came to the conclusion, but only after testing it wasn't a problem with allocation in general, that it directly involves the new operator. To test if allocation may be broken I ran similar tests with malloc and system calls, but both returned 0, null, as expected. Once again, I am only assuming the fault is with the new operator code in the libstdc++, and the way gcc optimizes the call, and can not be sure it is not a problem of gcc in generall.
>How-To-Repeat:
Even the simplest examples I have tested will see this error, and to that point here is one:

#include <cstdlib>
int main(){
char * s = new char[1024 * 1024 * 512];
if(s != 0) delete[] s;
std::system("");
return(0);}

On my machine I only have about 312 MB or so of ram free, and so I know this will fail, obviously it depends on exactly how much ram is currently in use and how much the test system has, and so to repeat the fail simply make sure to call new with enough memory to try and "grab" more memory than the system has available. I know the example is an unfair one as needing 512 MB of memory in a normal program is extremely rare, but that is only because I need to make sure to try and "grab" enough to make the call fail, and if more background applications had been running it would have been far less needed.
>Fix:
Assuming I am correct, then considering that malloc works I know that the allocation isn't the problem, and it must be new or the way g++ optimizes the new call. A possible fix would be to, at compile time, test the bounds of a call to new for very large grabs, greater than 30 or so MB, and check the malloc call, I have looked at some source of gcc, and belive I am following it correctly (that new in turn calls malloc), to make sure that the memory is valid before calling the constuctors. Of course, testing each and every call to new could get in the way speed and effecient code, and perhaps it is possible to keep track of how many times new has been called. If it is called a great many times then it should be validated at each call, or if it, as I previously suggested, is called with a very large number and one that will likely crash the system, but then again in the quest for faster code the checking and tracking of the new calls should be toggle able. For example, if -O3 is specified neither track or check for validity of any new call, for -O2 check for validity of large calls, for -O1 track for a large number of calls and check for validity of calls for big memory blocks and check every call after a certain number of calls, and for no specific speed optimizations simply check each call and every call to new for vailidity before constuction, this would be especially hand for small memory applications on embedded systems where less than 32 MB is norm.
>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="preproctxt.txt"
Content-Disposition: inline; filename="preproctxt.txt"

# 1 "main.cpp"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "main.cpp"
# 1 "D:/Progra~1/Dev-Cpp/include/c++/cstdlib" 1
# 48 "D:/Progra~1/Dev-Cpp/include/c++/cstdlib" 3

# 1 "D:/Progra~1/Dev-Cpp/include/c++/mingw32/bits/c++config.h" 1 3
# 34 "D:/Progra~1/Dev-Cpp/include/c++/mingw32/bits/c++config.h" 3
# 1 "D:/Progra~1/Dev-Cpp/include/c++/mingw32/bits/os_defines.h" 1 3
# 35 "D:/Progra~1/Dev-Cpp/include/c++/mingw32/bits/c++config.h" 2 3
# 50 "D:/Progra~1/Dev-Cpp/include/c++/cstdlib" 2 3
# 1 "D:/Progra~1/Dev-Cpp/include/c++/cstddef" 1 3
# 47 "D:/Progra~1/Dev-Cpp/include/c++/cstddef" 3

# 1 "D:/Progra~1/Dev-Cpp/include/stddef.h" 1 3





# 1 "D:/Progra~1/Dev-Cpp/include/stddef.h" 1 3





# 1 "D:/Progra~1/Dev-Cpp/lib/gcc-lib/mingw32/3.2/include/stddef.h" 1 3
# 149 "D:/Progra~1/Dev-Cpp/lib/gcc-lib/mingw32/3.2/include/stddef.h" 3
typedef int ptrdiff_t;
# 203 "D:/Progra~1/Dev-Cpp/lib/gcc-lib/mingw32/3.2/include/stddef.h" 3
typedef unsigned int size_t;
# 7 "D:/Progra~1/Dev-Cpp/include/stddef.h" 2 3
# 7 "D:/Progra~1/Dev-Cpp/include/stddef.h" 2 3
# 49 "D:/Progra~1/Dev-Cpp/include/c++/cstddef" 2 3

namespace std
{
  using ::ptrdiff_t;
  using ::size_t;
}
# 51 "D:/Progra~1/Dev-Cpp/include/c++/cstdlib" 2 3

# 1 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 1 3
# 31 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
# 1 "D:/Progra~1/Dev-Cpp/include/_mingw.h" 1 3
# 32 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 2 3






# 1 "D:/Progra~1/Dev-Cpp/include/stddef.h" 1 3





# 1 "D:/Progra~1/Dev-Cpp/include/stddef.h" 1 3





# 1 "D:/Progra~1/Dev-Cpp/lib/gcc-lib/mingw32/3.2/include/stddef.h" 1 3
# 7 "D:/Progra~1/Dev-Cpp/include/stddef.h" 2 3
# 7 "D:/Progra~1/Dev-Cpp/include/stddef.h" 2 3
# 39 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 2 3
# 77 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
extern "C" {
# 86 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
extern int _argc;
extern char** _argv;




extern int* __p___argc(void);
extern char*** __p___argv(void);
extern wchar_t*** __p___wargv(void);
# 129 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
   extern __attribute__((dllimport)) int __mb_cur_max;
# 153 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
int* _errno(void);


int* __doserrno(void);







  extern char *** __p__environ(void);
  extern wchar_t *** __p__wenviron(void);
# 187 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
  extern __attribute__((dllimport)) int _sys_nerr;
# 211 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
extern __attribute__((dllimport)) char* _sys_errlist[];
# 225 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
extern unsigned int* __p__osver(void);
extern unsigned int* __p__winver(void);
extern unsigned int* __p__winmajor(void);
extern unsigned int* __p__winminor(void);
# 269 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
char** __p__pgmptr(void);

wchar_t** __p__wpgmptr(void);
# 292 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
double atof (const char*);
int atoi (const char*);
long atol (const char*);
int _wtoi (const wchar_t *);
long _wtol (const wchar_t *);

double strtod (const char*, char**);

extern __inline__ float strtof (const char *nptr, char **endptr)
  { return (strtod (nptr, endptr));}


long strtol (const char*, char**, int);
unsigned long strtoul (const char*, char**, int);



double wcstod (const wchar_t*, wchar_t**);

extern __inline__ float wcstof( const wchar_t *nptr, wchar_t **endptr)
{ return (wcstod(nptr, endptr)); }


long wcstol (const wchar_t*, wchar_t**, int);
unsigned long wcstoul (const wchar_t*, wchar_t**, int);



size_t wcstombs (char*, const wchar_t*, size_t);
int wctomb (char*, wchar_t);

int mblen (const char*, size_t);
size_t mbstowcs (wchar_t*, const char*, size_t);
int mbtowc (wchar_t*, const char*, size_t);

int rand (void);
void srand (unsigned int);

void* calloc (size_t, size_t);
void* malloc (size_t);
void* realloc (void*, size_t);
void free (void*);

void abort (void) __attribute__ ((noreturn));
void exit (int) __attribute__ ((noreturn));
int atexit (void (*)(void));

int system (const char*);
char* getenv (const char*);

void* bsearch (const void*, const void*, size_t, size_t,
                 int (*)(const void*, const void*));
void qsort (const void*, size_t, size_t,
                 int (*)(const void*, const void*));

int abs (int);
long labs (long);
# 358 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
typedef struct { int quot, rem; } div_t;
typedef struct { long quot, rem; } ldiv_t;

div_t div (int, int);
ldiv_t ldiv (long, long);







void _beep (unsigned int, unsigned int);
void _seterrormode (int);
void _sleep (unsigned long);

void _exit (int) __attribute__ ((noreturn));


void _Exit(int) __attribute__ ((noreturn));
extern __inline__ void _Exit(int status)
        { _exit(status); }


typedef int (* _onexit_t)(void);
_onexit_t _onexit( _onexit_t );

int _putenv (const char*);
void _searchenv (const char*, const char*, char*);


char* _ecvt (double, int, int*, int*);
char* _fcvt (double, int, int*, int*);
char* _gcvt (double, int, char*);

void _makepath (char*, const char*, const char*, const char*, const char*);
void _splitpath (const char*, char*, char*, char*, char*);
char* _fullpath (char*, const char*, size_t);


char* _itoa (int, char*, int);
char* _ltoa (long, char*, int);
char* _ultoa(unsigned long, char*, int);
wchar_t* _itow (int, wchar_t*, int);
wchar_t* _ltow (long, wchar_t*, int);
wchar_t* _ultow (unsigned long, wchar_t*, int);


long long _atoi64(const char *);
char* _i64toa(long long, char *, int);
char* _ui64toa(unsigned long long, char *, int);
long long _wtoi64(const wchar_t *);
wchar_t* _i64tow(long long, wchar_t *, int);
wchar_t* _ui64tow(unsigned long long, wchar_t *, int);

wchar_t* _wgetenv(const wchar_t*);
int _wputenv(const wchar_t*);
void _wsearchenv(const wchar_t*, const wchar_t*, wchar_t*);
void _wmakepath(wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*, const wchar_t*);
void _wsplitpath (const wchar_t*, wchar_t*, wchar_t*, wchar_t*, wchar_t*);
wchar_t* _wfullpath (wchar_t*, const wchar_t*, size_t);

unsigned int _rotl(unsigned int, int);
unsigned int _rotr(unsigned int, int);
unsigned long _lrotl(unsigned long, int);
unsigned long _lrotr(unsigned long, int);




int putenv (const char*);
void searchenv (const char*, const char*, char*);

char* itoa (int, char*, int);
char* ltoa (long, char*, int);


char* ecvt (double, int, int*, int*);
char* fcvt (double, int, int*, int*);
char* gcvt (double, int, char*);
# 447 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
typedef struct { long long quot, rem; } lldiv_t;

lldiv_t lldiv (long long, long long);

extern __inline__ long long llabs(long long _j)
  {return (_j >= 0 ? _j : -_j);}

long long strtoll (const char* __restrict__, char** __restrict, int);
unsigned long long strtoull (const char* __restrict__, char** __restrict__, int);


long long atoll (const char *);


long long wtoll(const wchar_t *);
char* lltoa(long long, char *, int);
char* ulltoa(unsigned long long , char *, int);
wchar_t* lltow(long long, wchar_t *, int);
wchar_t* ulltow(unsigned long long, wchar_t *, int);


extern __inline__ long long atoll (const char * _c)
        { return _atoi64 (_c); }
extern __inline__ char* lltoa(long long _n, char * _c, int _i)
        { return _i64toa (_n, _c, _i); }
extern __inline__ char* ulltoa(unsigned long long _n, char * _c, int _i)
        { return _ui64toa (_n, _c, _i); }
extern __inline__ long long wtoll(const wchar_t * _w)
        { return _wtoi64 (_w); }
extern __inline__ wchar_t* lltow(long long _n, wchar_t * _w, int _i)
        { return _i64tow (_n, _w, _i); }
extern __inline__ wchar_t* ulltow(unsigned long long _n, wchar_t * _w, int _i)
        { return _ui64tow (_n, _w, _i); }
# 492 "D:/Progra~1/Dev-Cpp/include/stdlib.h" 3
}
# 53 "D:/Progra~1/Dev-Cpp/include/c++/cstdlib" 2 3
# 84 "D:/Progra~1/Dev-Cpp/include/c++/cstdlib" 3
namespace std
{
  using ::div_t;
  using ::ldiv_t;

  using ::abort;
  using ::abs;
  using ::atexit;
  using ::atof;
  using ::atoi;
  using ::atol;
  using ::bsearch;
  using ::calloc;
  using ::div;
  using ::exit;
  using ::free;
  using ::getenv;
  using ::labs;
  using ::ldiv;
  using ::malloc;
  using ::mblen;
  using ::mbstowcs;
  using ::mbtowc;
  using ::qsort;
  using ::rand;
  using ::realloc;
  using ::srand;
  using ::strtod;
  using ::strtol;
  using ::strtoul;
  using ::system;
  using ::wcstombs;
  using ::wctomb;

  inline long
  abs(long __i) { return labs(__i); }

  inline ldiv_t
  div(long __i, long __j) { return ldiv(__i, __j); }
}
# 2 "main.cpp" 2

int main(){
char * s = new char[1024 * 1024 * 512];
if(s != 0) delete[] s;
std::system("PAUSE");
return(0);}


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

end of thread, other threads:[~2003-04-01 14:29 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-01 14:29 libstdc++/10283: operator new does not return null on some windows systems bangerth
  -- strict thread matches above, loose matches on Subject: below --
2003-04-01  6:16 Tim Prince
2003-04-01  4:36 zerovalintine

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