mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0024836: Stack overflow when raising exception in low memory condition
Standard_OutOfMemory exception is refactored so as to avoid memory allocations (which will likely fail) when it is raised: - method NewInstance() returns static instance (singleton) - method Raise() raises copy of that singleton, resetting its message string - message string is stored as field, not allocated dynamically (thus maximum message length is limited by buffer size) Class Standard_Failure slightly revised: method Destroy() is merged to destructor, methods Get/SetMessageString() are made virtual. Add test case for the bug
This commit is contained in:
@@ -73,7 +73,7 @@ void* NCollection_WinHeapAllocator::Allocate (const Standard_Size theSize)
|
|||||||
if (aResult == NULL)
|
if (aResult == NULL)
|
||||||
{
|
{
|
||||||
char aBuf[128];
|
char aBuf[128];
|
||||||
Sprintf (aBuf, "Failed to allocate " PRIuPTR " bytes in local dynamic heap", theSize);
|
Sprintf (aBuf, "Failed to allocate %" PRIuPTR " bytes in local dynamic heap", theSize);
|
||||||
Standard_OutOfMemory::Raise (aBuf);
|
Standard_OutOfMemory::Raise (aBuf);
|
||||||
}
|
}
|
||||||
return aResult;
|
return aResult;
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include <gp_Ax2.hxx>
|
#include <gp_Ax2.hxx>
|
||||||
#include <Geom_Circle.hxx>
|
#include <Geom_Circle.hxx>
|
||||||
#include <Geom_SurfaceOfLinearExtrusion.hxx>
|
#include <Geom_SurfaceOfLinearExtrusion.hxx>
|
||||||
|
#include <NCollection_List.hxx>
|
||||||
#include <TColgp_Array2OfPnt.hxx>
|
#include <TColgp_Array2OfPnt.hxx>
|
||||||
#include <TColStd_Array2OfReal.hxx>
|
#include <TColStd_Array2OfReal.hxx>
|
||||||
#include <TColStd_Array1OfReal.hxx>
|
#include <TColStd_Array1OfReal.hxx>
|
||||||
@@ -1251,6 +1252,82 @@ static Standard_Integer SurfaceGenOCC26675_1( Draw_Interpretor& theDI,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace AllocTest
|
||||||
|
{
|
||||||
|
// The test is based of occupying of all available virtual memory.
|
||||||
|
// Obviously it has no sense on 64-bit platforms.
|
||||||
|
|
||||||
|
enum Status
|
||||||
|
{
|
||||||
|
NotApplicable = 0x1,
|
||||||
|
OUMCatchOK = 0x2,
|
||||||
|
OUMCatchFail = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int> int test()
|
||||||
|
{
|
||||||
|
// non-32-bit implementation
|
||||||
|
return NotApplicable;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> int test<4>()
|
||||||
|
{
|
||||||
|
// 32-bit implementation
|
||||||
|
NCollection_List<Standard_Address> aList;
|
||||||
|
const Standard_Integer aBlockSizes[] = {100000, 10000, 10};
|
||||||
|
int aStatus = 0;
|
||||||
|
|
||||||
|
// start populate memory with blocks of large size, then
|
||||||
|
// smaller ones and so on according to content of the array aBlockSizes
|
||||||
|
for (size_t i=0; i < sizeof(aBlockSizes)/sizeof(int); i++)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
aList.Append(Standard::Allocate(aBlockSizes[i]));
|
||||||
|
}
|
||||||
|
catch (Standard_Failure)
|
||||||
|
{
|
||||||
|
aStatus |= OUMCatchOK;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
aStatus |= OUMCatchFail;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// release all allocated blocks
|
||||||
|
for (NCollection_List<Standard_Address>::Iterator it(aList); it.More(); it.Next())
|
||||||
|
{
|
||||||
|
Standard::Free(it.Value());
|
||||||
|
}
|
||||||
|
return aStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : OCC24836
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
static Standard_Integer OCC24836 (Draw_Interpretor& theDI, Standard_Integer n, const char** a)
|
||||||
|
{
|
||||||
|
if (n != 1)
|
||||||
|
{
|
||||||
|
theDI << "Usage : " << a[0] << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aStatus = AllocTest::test<sizeof(size_t)>();
|
||||||
|
|
||||||
|
if (aStatus & AllocTest::NotApplicable)
|
||||||
|
theDI << "This test case is not applicable for 64-bit and higher platforms\n";
|
||||||
|
if (aStatus & AllocTest::OUMCatchOK)
|
||||||
|
theDI << "out-of-memory has been caught: OK\n";
|
||||||
|
if (aStatus & AllocTest::OUMCatchFail)
|
||||||
|
theDI << "Error: out-of-memory is not always caught\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : OCC27021
|
//function : OCC27021
|
||||||
@@ -1346,6 +1423,7 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
|
|||||||
const char *group = "QABugs";
|
const char *group = "QABugs";
|
||||||
|
|
||||||
theCommands.Add ("OCC26675_1", "OCC26675_1 result", __FILE__, SurfaceGenOCC26675_1, group);
|
theCommands.Add ("OCC26675_1", "OCC26675_1 result", __FILE__, SurfaceGenOCC26675_1, group);
|
||||||
|
theCommands.Add ("OCC24836", "OCC24836", __FILE__, OCC24836, group);
|
||||||
theCommands.Add("OCC27021", "OCC27021", __FILE__, OCC27021, group);
|
theCommands.Add("OCC27021", "OCC27021", __FILE__, OCC27021, group);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@@ -29,7 +29,6 @@ Standard_ExtString.cxx
|
|||||||
Standard_ExtString.hxx
|
Standard_ExtString.hxx
|
||||||
Standard_Failure.cxx
|
Standard_Failure.cxx
|
||||||
Standard_Failure.hxx
|
Standard_Failure.hxx
|
||||||
Standard_Failure.lxx
|
|
||||||
Standard_GUID.cxx
|
Standard_GUID.cxx
|
||||||
Standard_GUID.hxx
|
Standard_GUID.hxx
|
||||||
Standard_Handle.hxx
|
Standard_Handle.hxx
|
||||||
@@ -62,6 +61,7 @@ Standard_NullObject.hxx
|
|||||||
Standard_NullValue.hxx
|
Standard_NullValue.hxx
|
||||||
Standard_NumericError.hxx
|
Standard_NumericError.hxx
|
||||||
Standard_OStream.hxx
|
Standard_OStream.hxx
|
||||||
|
Standard_OutOfMemory.cxx
|
||||||
Standard_OutOfMemory.hxx
|
Standard_OutOfMemory.hxx
|
||||||
Standard_OutOfRange.hxx
|
Standard_OutOfRange.hxx
|
||||||
Standard_Overflow.hxx
|
Standard_Overflow.hxx
|
||||||
|
@@ -88,7 +88,7 @@ Standard_Failure::Standard_Failure (const Standard_Failure& theFailure)
|
|||||||
myMessage = copy_message(theFailure.myMessage);
|
myMessage = copy_message(theFailure.myMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Standard_Failure::Destroy()
|
Standard_Failure::~Standard_Failure()
|
||||||
{
|
{
|
||||||
deallocate_message(myMessage);
|
deallocate_message(myMessage);
|
||||||
}
|
}
|
||||||
@@ -195,3 +195,13 @@ Handle(Standard_Failure) Standard_Failure::NewInstance(const Standard_CString AS
|
|||||||
{
|
{
|
||||||
return new Standard_Failure(AString) ;
|
return new Standard_Failure(AString) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : GetMessageString
|
||||||
|
//purpose : Returns error message
|
||||||
|
//=======================================================================
|
||||||
|
Standard_CString Standard_Failure::GetMessageString () const
|
||||||
|
{
|
||||||
|
return (myMessage ? myMessage+sizeof(Standard_Integer) : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -41,19 +41,18 @@ public:
|
|||||||
|
|
||||||
//! Creates a status object of type "Failure".
|
//! Creates a status object of type "Failure".
|
||||||
Standard_EXPORT Standard_Failure();
|
Standard_EXPORT Standard_Failure();
|
||||||
Standard_EXPORT Standard_Failure (const Standard_Failure& f);
|
|
||||||
|
|
||||||
|
//! Copy constructor
|
||||||
|
Standard_EXPORT Standard_Failure (const Standard_Failure& f);
|
||||||
|
|
||||||
//! Creates a status object of type "Failure".
|
//! Creates a status object of type "Failure".
|
||||||
Standard_EXPORT Standard_Failure(const Standard_CString aString);
|
Standard_EXPORT Standard_Failure(const Standard_CString aString);
|
||||||
Standard_EXPORT Standard_Failure& operator= (const Standard_Failure& f);
|
|
||||||
|
|
||||||
Standard_EXPORT void Destroy();
|
//! Assignment operator
|
||||||
~Standard_Failure()
|
Standard_EXPORT Standard_Failure& operator= (const Standard_Failure& f);
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//! Destructor
|
||||||
|
Standard_EXPORT ~Standard_Failure();
|
||||||
|
|
||||||
//! Prints on the stream <s> the exception name followed by
|
//! Prints on the stream <s> the exception name followed by
|
||||||
//! the error message.
|
//! the error message.
|
||||||
@@ -63,16 +62,12 @@ Standard_EXPORT Standard_Failure& operator= (const Standard_Failure& f);
|
|||||||
//! Handle(Standard_Failure)&)"
|
//! Handle(Standard_Failure)&)"
|
||||||
//! is implemented. (This operator uses the method Print)
|
//! is implemented. (This operator uses the method Print)
|
||||||
Standard_EXPORT void Print (Standard_OStream& s) const;
|
Standard_EXPORT void Print (Standard_OStream& s) const;
|
||||||
void operator<< (Standard_OStream& s) const
|
|
||||||
{
|
|
||||||
Print(s);
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Returns error message
|
//! Returns error message
|
||||||
Standard_CString GetMessageString() const;
|
Standard_EXPORT virtual Standard_CString GetMessageString() const;
|
||||||
|
|
||||||
//! Sets error message
|
//! Sets error message
|
||||||
Standard_EXPORT void SetMessageString (const Standard_CString aMessage);
|
Standard_EXPORT virtual void SetMessageString (const Standard_CString aMessage);
|
||||||
|
|
||||||
Standard_EXPORT void Reraise();
|
Standard_EXPORT void Reraise();
|
||||||
|
|
||||||
@@ -133,11 +128,11 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline Standard_OStream& operator << (Standard_OStream& AStream,
|
||||||
#include <Standard_Failure.lxx>
|
const Handle(Standard_Failure)& AFailure)
|
||||||
|
{
|
||||||
|
AFailure->Print(AStream);
|
||||||
|
return AStream;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // _Standard_Failure_HeaderFile
|
#endif // _Standard_Failure_HeaderFile
|
||||||
|
@@ -1,37 +0,0 @@
|
|||||||
// Copyright (c) 1998-1999 Matra Datavision
|
|
||||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
||||||
//
|
|
||||||
// This file is part of Open CASCADE Technology software library.
|
|
||||||
//
|
|
||||||
// This library is free software; you can redistribute it and/or modify it under
|
|
||||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
||||||
// by the Free Software Foundation, with special exception defined in the file
|
|
||||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
||||||
// distribution for complete text of the license and disclaimer of any warranty.
|
|
||||||
//
|
|
||||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
||||||
// commercial license or contractual agreement.
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
// Print (me; s: in out OStream) returns OStream;
|
|
||||||
// ------------------------------------------------------------------
|
|
||||||
//++++ void Standard_Failure::Print (Standard_OStream& AStream) const
|
|
||||||
//++++ {
|
|
||||||
//++++ AStream << ": " << myMessage << endl;
|
|
||||||
|
|
||||||
inline Standard_OStream& operator <<(Standard_OStream& AStream,
|
|
||||||
const Handle(Standard_Failure)& AFailure)
|
|
||||||
{
|
|
||||||
AFailure->Print(AStream);
|
|
||||||
return AStream;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=======================================================================
|
|
||||||
//function : GetMessageString
|
|
||||||
//purpose : Returns error message
|
|
||||||
//=======================================================================
|
|
||||||
inline Standard_CString Standard_Failure::GetMessageString () const
|
|
||||||
{
|
|
||||||
return (myMessage ? myMessage+sizeof(Standard_Integer) : myMessage);
|
|
||||||
}
|
|
||||||
|
|
@@ -132,10 +132,6 @@ extern "C" int getpagesize() ;
|
|||||||
#define GET_USER(block) (((Standard_Size*)(block)) + BLOCK_SHIFT)
|
#define GET_USER(block) (((Standard_Size*)(block)) + BLOCK_SHIFT)
|
||||||
#define GET_BLOCK(storage) (((Standard_Size*)(storage))-BLOCK_SHIFT)
|
#define GET_BLOCK(storage) (((Standard_Size*)(storage))-BLOCK_SHIFT)
|
||||||
|
|
||||||
// create static instance of out-of-memory exception to protect
|
|
||||||
// against possible lack of memory for its raising
|
|
||||||
static Handle(Standard_OutOfMemory) anOutOfMemError = new Standard_OutOfMemory;
|
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
//function : Standard_MMgr
|
//function : Standard_MMgr
|
||||||
//purpose :
|
//purpose :
|
||||||
@@ -400,7 +396,7 @@ Standard_Address Standard_MMgrOpt::Allocate(const Standard_Size aSize)
|
|||||||
aBlock = (Standard_Size*)calloc(RoundSizeN+BLOCK_SHIFT, sizeof(Standard_Size));
|
aBlock = (Standard_Size*)calloc(RoundSizeN+BLOCK_SHIFT, sizeof(Standard_Size));
|
||||||
// if still not succeeded, raise exception
|
// if still not succeeded, raise exception
|
||||||
if ( ! aBlock )
|
if ( ! aBlock )
|
||||||
anOutOfMemError->Reraise ("Standard_MMgrOpt::Allocate(): malloc failed");
|
Standard_OutOfMemory::Raise ("Standard_MMgrOpt::Allocate(): malloc failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize new block header by its size
|
// initialize new block header by its size
|
||||||
@@ -725,7 +721,7 @@ retry:
|
|||||||
if ( Purge(Standard_False) )
|
if ( Purge(Standard_False) )
|
||||||
goto retry;
|
goto retry;
|
||||||
// if nothing helps, raise exception
|
// if nothing helps, raise exception
|
||||||
anOutOfMemError->Reraise (strerror(errcode));
|
Standard_OutOfMemory::Raise (strerror(errcode));
|
||||||
}
|
}
|
||||||
|
|
||||||
// save actually allocated size into argument
|
// save actually allocated size into argument
|
||||||
@@ -759,7 +755,7 @@ retry:
|
|||||||
char message[BUFSIZE];
|
char message[BUFSIZE];
|
||||||
if ( FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, message, BUFSIZE-1, 0) <=0 )
|
if ( FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, message, BUFSIZE-1, 0) <=0 )
|
||||||
strcpy (message, "Standard_MMgrOpt::AllocMemory() failed to mmap");
|
strcpy (message, "Standard_MMgrOpt::AllocMemory() failed to mmap");
|
||||||
anOutOfMemError->Reraise (message);
|
Standard_OutOfMemory::Raise (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// record map handle in the beginning
|
// record map handle in the beginning
|
||||||
@@ -782,7 +778,7 @@ retry:
|
|||||||
if ( Purge(Standard_False) )
|
if ( Purge(Standard_False) )
|
||||||
goto retry;
|
goto retry;
|
||||||
// if nothing helps, raise exception
|
// if nothing helps, raise exception
|
||||||
anOutOfMemError->Reraise ("Standard_MMgrOpt::Allocate(): malloc failed");
|
Standard_OutOfMemory::Raise ("Standard_MMgrOpt::Allocate(): malloc failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// clear whole block if clearing option is set
|
// clear whole block if clearing option is set
|
||||||
|
102
src/Standard/Standard_OutOfMemory.cxx
Normal file
102
src/Standard/Standard_OutOfMemory.cxx
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
// Created on: 2016-01-06
|
||||||
|
// Created by: Andrey Betenev
|
||||||
|
// Copyright (c) 2016 OPEN CASCADE SAS
|
||||||
|
//
|
||||||
|
// This file is part of Open CASCADE Technology software library.
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or modify it under
|
||||||
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||||
|
// by the Free Software Foundation, with special exception defined in the file
|
||||||
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||||
|
// distribution for complete text of the license and disclaimer of any warranty.
|
||||||
|
//
|
||||||
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||||
|
// commercial license or contractual agreement.
|
||||||
|
|
||||||
|
#include <Standard_OutOfMemory.hxx>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
IMPLEMENT_STANDARD_RTTIEXT(Standard_OutOfMemory,Standard_ProgramError)
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Standard_OutOfMemory
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
Standard_OutOfMemory::Standard_OutOfMemory(const Standard_CString theMessage)
|
||||||
|
{
|
||||||
|
// call explicitly own method (non-virtual call)
|
||||||
|
Standard_OutOfMemory::SetMessageString (theMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : GetMessageString
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
Standard_CString Standard_OutOfMemory::GetMessageString() const
|
||||||
|
{
|
||||||
|
return myBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : SetMessageString
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
void Standard_OutOfMemory::SetMessageString (const Standard_CString theMessage)
|
||||||
|
{
|
||||||
|
// restrict length of the message by buffer size
|
||||||
|
size_t n = (theMessage ? std::min (strlen (theMessage), sizeof(myBuffer) - 1) : 0);
|
||||||
|
|
||||||
|
// first set line end symbol to be safe in case of concurrent call
|
||||||
|
myBuffer[n] = '\0';
|
||||||
|
if (n > 0)
|
||||||
|
memcpy (myBuffer, theMessage, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Raise
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
void Standard_OutOfMemory::Raise(const Standard_CString theMessage)
|
||||||
|
{
|
||||||
|
NewInstance(theMessage)->Reraise();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Raise
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
void Standard_OutOfMemory::Raise(Standard_SStream& theMessage)
|
||||||
|
{
|
||||||
|
NewInstance(theMessage.str().c_str())->Reraise();
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : NewInstance
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
// global instance must be allocated at load-time
|
||||||
|
static Handle(Standard_OutOfMemory) anOutOfMemInstance = new Standard_OutOfMemory;
|
||||||
|
|
||||||
|
Handle(Standard_OutOfMemory) Standard_OutOfMemory::NewInstance(const Standard_CString theMessage)
|
||||||
|
{
|
||||||
|
anOutOfMemInstance->SetMessageString (theMessage);
|
||||||
|
return anOutOfMemInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=======================================================================
|
||||||
|
//function : Throw
|
||||||
|
//purpose :
|
||||||
|
//=======================================================================
|
||||||
|
|
||||||
|
void Standard_OutOfMemory::Throw () const
|
||||||
|
{
|
||||||
|
throw *this;
|
||||||
|
}
|
@@ -32,6 +32,48 @@ DEFINE_STANDARD_HANDLE(Standard_OutOfMemory, Standard_ProgramError)
|
|||||||
#define Standard_OutOfMemory_Raise_if(CONDITION, MESSAGE)
|
#define Standard_OutOfMemory_Raise_if(CONDITION, MESSAGE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEFINE_STANDARD_EXCEPTION(Standard_OutOfMemory, Standard_ProgramError)
|
//! Standard_OutOfMemory exception is defined explicitly and not by
|
||||||
|
//! macro DEFINE_STANDARD_EXCEPTION, to avoid necessity of dynamic
|
||||||
|
//! memory allocations during throwing and stack unwinding:
|
||||||
|
//!
|
||||||
|
//! - method NewInstance() returns static instance (singleton)
|
||||||
|
//! - method Raise() raises copy of that singleton, resetting
|
||||||
|
//! its message string
|
||||||
|
//! - message string is stored as field, not allocated dynamically
|
||||||
|
//! (storable message length is limited by buffer size)
|
||||||
|
//!
|
||||||
|
//! The reason is that in out-of-memory condition any memory allocation can
|
||||||
|
//! fail, thus use of operator new for allocation of new exception instance
|
||||||
|
//! is dangerous (can cause recursion until stack overflow, see #24836).
|
||||||
|
|
||||||
|
class Standard_OutOfMemory : public Standard_ProgramError
|
||||||
|
{
|
||||||
|
void Throw () const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Constructor is kept public for backward compatibility
|
||||||
|
Standard_EXPORT Standard_OutOfMemory(const Standard_CString theMessage = 0);
|
||||||
|
|
||||||
|
//! Returns error message
|
||||||
|
Standard_EXPORT Standard_CString GetMessageString() const Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Sets error message
|
||||||
|
Standard_EXPORT void SetMessageString (const Standard_CString aMessage) Standard_OVERRIDE;
|
||||||
|
|
||||||
|
//! Raises exception with specified message string
|
||||||
|
Standard_EXPORT static void Raise(const Standard_CString theMessage = "");
|
||||||
|
|
||||||
|
//! Raises exception with specified message string
|
||||||
|
Standard_EXPORT static void Raise(Standard_SStream& theMessage);
|
||||||
|
|
||||||
|
//! Returns global instance of exception
|
||||||
|
Standard_EXPORT static Handle(Standard_OutOfMemory) NewInstance(const Standard_CString theMessage = "");
|
||||||
|
|
||||||
|
DEFINE_STANDARD_RTTIEXT(Standard_OutOfMemory,Standard_ProgramError)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
char myBuffer[1024];
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _Standard_OutOfMemory_HeaderFile
|
#endif // _Standard_OutOfMemory_HeaderFile
|
||||||
|
11
tests/bugs/fclasses/bug24836
Normal file
11
tests/bugs/fclasses/bug24836
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
puts "============"
|
||||||
|
puts "OCC24836"
|
||||||
|
puts "============"
|
||||||
|
puts ""
|
||||||
|
#######################################################################
|
||||||
|
# Stack overflow when raising exception in low memory condition
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
pload QAcommands
|
||||||
|
|
||||||
|
OCC24836
|
Reference in New Issue
Block a user