Allocation during process exit

C

Christopher

I need some ammunition to convince some people that a bug I found is a
bug.

Is it at the very least, undefined behavior, if a call to new is made
after the process has begun to exit and after the global and static
deallocation sequence has begun?

After all, how can I allocate a new global when the process is trying
to deallocate all globals?

Is there any documentation on the matter I can use for convincing
power?
 
V

Victor Bazarov

Christopher said:
I need some ammunition to convince some people that a bug I found is a
bug.

Is it at the very least, undefined behavior, if a call to new is made
after the process has begun to exit and after the global and static
deallocation sequence has begun?

No, AFAIK.
After all, how can I allocate a new global when the process is trying
to deallocate all globals?

Who said anything about allocating "a new global"? Dynamic storage
duration and static storage duration are not the same thing.
Is there any documentation on the matter I can use for convincing
power?

Waving a book or anything else will not necessarily help. Genearally
speaking, allocations are orthogonal to the stages of program unless
the allocations somehow depend on the state that changes. Dynamically
allocating an object is OK, except if it's not due to other reasons,
like with a pooled memory manager, the manager is under destruction or
the pool has already been deactivated by the manager... So it all
depends on how you do that dynamic allocation.

V
 
C

Christopher

Who said anything about allocating "a new global"? Dynamic storage
duration and static storage duration are not the same thing.

Its hard to say as I don't have access to the source causing the
problem, only my dependent source, but looking at the call stack it
appears as though:

1 the process has begun termination
2 global and statics have begun to be deallocated
3 some class in its deconstruction makes a call to a singleton's
GetInstance() method
4 the singleton, in turn, attempts to allocate itself using new and
its constructor,
5 new calls malloc
6 malloc calls _int_malloc
7 _int_ malloc calls _malloc_consolidate()
8 process hangs and never exits

I use the word 'global' to describe the singleton, as its usually a
pointer or reference defined globally which points to or refers to
some memory on the heap.
 
M

Marcel Müller

Christopher said:
Its hard to say as I don't have access to the source causing the
problem, only my dependent source, but looking at the call stack it
appears as though:

1 the process has begun termination
2 global and statics have begun to be deallocated
3 some class in its deconstruction makes a call to a singleton's
GetInstance() method
4 the singleton, in turn, attempts to allocate itself using new and
its constructor,
5 new calls malloc
6 malloc calls _int_malloc
7 _int_ malloc calls _malloc_consolidate()
8 process hangs and never exits

I use the word 'global' to describe the singleton, as its usually a
pointer or reference defined globally which points to or refers to
some memory on the heap.

I think this might be part of the Problem. If the singleton is already
destroyed by the global deallocation the static storage becomes invalid
and accessing it is undefined bahaviour. Furthermore if the singleton is
guaranteed to be thread-safe, the code may access global mutexes and
they either may be no longer valid or they are entered recursively for
some reason. Since your hang is in the C runtime it is likely that the
mutex of the standard memory manager is involved.

If the Singleton is not instantiated anywhere before the program exits,
I would simply try to force the initialization somewhere else in the code.


Marcel
 
V

Victor Bazarov

Christopher said:
Its hard to say as I don't have access to the source causing the
problem, only my dependent source, but looking at the call stack it
appears as though:

1 the process has begun termination
2 global and statics have begun to be deallocated
3 some class in its deconstruction makes a call to a singleton's
GetInstance() method
4 the singleton, in turn, attempts to allocate itself using new and
its constructor,
5 new calls malloc
6 malloc calls _int_malloc
7 _int_ malloc calls _malloc_consolidate()
8 process hangs and never exits

Well... You see, '_int_malloc' or '_malloc_consolicate' are not C++
terms, they are implementation details. You could try finding out
more about those by contacting the creator of the standard library
you're using.
I use the word 'global' to describe the singleton, as its usually a
pointer or reference defined globally which points to or refers to
some memory on the heap.

Sounds like you need a better implementation of your singleton.
The class deconstrucing itself should attempt checking the validity
(existence) of the singletons and act accordingly. Try adding some
kind of "isOK" static member to your singleton, let it only set the
member after the instance is created and let it clear the member
when the singleton is destructed. Make a policy to never access
any objects after they've been destructed (that's UB, BTW). Make
sure the "some class" can actually behave acceptably without the
singleton that may have already been destructed.

V
 
C

Christopher

Its hard to say as I don't have access to the source causing the
problem, only my dependent source, but looking at the call stack it
appears as though:
1 the process has begun termination
2 global and statics have begun to be deallocated
3 some class in its deconstruction makes a call to a singleton's
GetInstance() method
4 the singleton, in turn, attempts to allocate itself using new and
its constructor,
5 new calls malloc
6 malloc calls _int_malloc
7 _int_ malloc calls _malloc_consolidate()
8 process hangs and never exits

Well... You see, '_int_malloc' or '_malloc_consolicate' are not C++
terms, they are implementation details. You could try finding out
more about those by contacting the creator of the standard library
you're using.
I use the word 'global' to describe the singleton, as its usually a
pointer or reference defined globally which points to or refers to
some memory on the heap.

Sounds like you need a better implementation of your singleton.
The class deconstrucing itself should attempt checking the validity
(existence) of the singletons and act accordingly. Try adding some
kind of "isOK" static member to your singleton, let it only set the
member after the instance is created and let it clear the member
when the singleton is destructed. Make a policy to never access
any objects after they've been destructed (that's UB, BTW). Make
sure the "some class" can actually behave acceptably without the
singleton that may have already been destructed.

V


Wish I could. My source is way up above all that. All I can do is yell
at venders that theirs is broken. All I've got access to for this
entrire call stack is a header and a compiled lib.
 
J

James Kanze

Who said anything about allocating "a new global"? Dynamic
storage duration and static storage duration are not the
same thing.
[/QUOTE]
Its hard to say as I don't have access to the source causing
the problem, only my dependent source, but looking at the call
stack it appears as though:
1 the process has begun termination
2 global and statics have begun to be deallocated

Objects with static lifetime are never deallocated. If they
have non trivial destructors, the destructors are called (along
with any functions registered with atexit) when exit() is called
(normally by returning from main). System services are required
to work at least until this phase has finished.
3 some class in its deconstruction makes a call to a singleton's
GetInstance() method
4 the singleton, in turn, attempts to allocate itself using new and
its constructor,
5 new calls malloc
6 malloc calls _int_malloc
7 _int_ malloc calls _malloc_consolidate()
8 process hangs and never exits

Most likely, you've corrupted the free space arena somewhere
previously. Malloc and operator new are required to work until
all user code has finished executing, and I've never seen a
system where this wasn't the case.
I use the word 'global' to describe the singleton, as its
usually a pointer or reference defined globally which points
to or refers to some memory on the heap.

Actually, one frequent singleton idiom is to use a static
variable in the instance() function. Usually, when a pointer is
used, it is because the author of the singleton doesn't want its
destructor called. Ever.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,950
Members
47,500
Latest member
ArianneJsb

Latest Threads

Top