overriding placement new + memory management

  • Thread starter Lagarde Sébastien
  • Start date
L

Lagarde Sébastien

Hello,

I write code to debug new call with following macro:
#define new (MemoryManager::Get().setOwner (__FILE__, __LINE__, _FUNCTION-),
FALSE) ? NULL : new

The setOwner allow to save the current file, line and function:

setOwner(const char *file, const u32 line, const char *func)
{
sourceFile = file;
sourceLine = line;
sourceFunc = func;
}

Then I can use this information to show some debug with an overloaded global
new opertor
void *operator new(size_t reportedSize)
{
use information
do normal new code
}

(This is the fluid studio memory manager)

This macro allow to deal with placement new.
My problem is that I need to have this debug informaiton thread safe.
So I put a critical section in Set Owner and leave it in operator new.

setOwner(const char *file, const u32 line, const char *func)
{
EnterCriticalSection()
sourceFile = file;
sourceLine = line;
sourceFunc = func;
}

void *operator new(size_t reportedSize)
{
use information
do normal new code
LeaveCriticalSection()
}

The problem is with placement new, : I don't want to debug placement new,
this is not required, but
as my macro is there I enter in SetOwner, so in the critical section but
never
leave...
So to resolve the problem I wrote my own version of placement new:

inline void* __cdecl operator new[](size_t, void* anywhere)
{
leaveCriticalSection();
return anywhere;
}

but my version of placement news seems to never been call and I block in
critical section.
I read on a web page that replacing global placement new is illegal. Is it
true ?
I try to force the usage of my placement new with some compiler specific
macro
(like define
#define __PLACEMENT_NEW_INLINE
#define __PLACEMENT_VEC_NEW_INLINE for visual 2005
before to include my own) but this seems not work.

any idea about own to force the use of my placement new ? Is it possible ?
or anybody have a better idea to debug with multithreading.

I know that i can't do an undef macro before the placement new and redo the
macro after, but as
I want to integrate external source code, I want to be able to use external
source without to have
to modify each placement new.

Thanks for your anwser.

Cheers

Sebastion Lagarde.
 
S

Sylvester Hesp

Lagarde Sébastien said:
Hello,

[... snip ...]

any idea about own to force the use of my placement new ? Is it possible ?
or anybody have a better idea to debug with multithreading.

Can't you just make use of thread local variables? That way you don't have
to use a critical section as each thread is using it's own set of variables.

- Sylvester Hesp
 
L

Lagarde Sébastien

It sound like a good idea,
I think a problem is that I have a lot of variable, (lot of statistic and
other),

I will check this. Thanks.

Any other esaier way ?

Sylvester Hesp said:
Lagarde Sébastien said:
Hello,

[... snip ...]

any idea about own to force the use of my placement new ? Is it possible
?
or anybody have a better idea to debug with multithreading.

Can't you just make use of thread local variables? That way you don't have
to use a critical section as each thread is using it's own set of
variables.

- Sylvester Hesp
 
L

Lagarde Sébastien

I found the problem of the TLS approch.
The problem is that i can allocate memory in a thread and free it in another
thread.
if I use TLS, I can't track my pointer...

Sylvester Hesp said:
Lagarde Sébastien said:
Hello,

[... snip ...]

any idea about own to force the use of my placement new ? Is it possible
?
or anybody have a better idea to debug with multithreading.

Can't you just make use of thread local variables? That way you don't have
to use a critical section as each thread is using it's own set of
variables.

- Sylvester Hesp
 
J

James Kanze

I write code to debug new call with following macro:
#define new (MemoryManager::Get().setOwner (__FILE__, __LINE__, _FUNCTION-),
FALSE) ? NULL : new

[...]
The problem is with placement new, : I don't want to debug
placement new, this is not required, but as my macro is there
I enter in SetOwner, so in the critical section but never
leave...
So to resolve the problem I wrote my own version of placement new:
inline void* __cdecl operator new[](size_t, void* anywhere)
{
leaveCriticalSection();
return anywhere;
}
but my version of placement news seems to never been call and I block in
critical section.

If operator new is inline, then the original version has already
been compiled into the library code.

Formally, using #define to define a keyword is undefined
behavior if you include any standard header. Practically, I
wouldn't be a bit surprised if it didn't cause problems if you
do it before including the standard headers: all it takes is for
a template to be used in two different translation units.

The usual solution here is to write system specific code to do a
stack walkback in the debugging operator new. This only gives
you a hex dump of the stack, to begin with, but it's not as if
you need to use the information that often, and usually, there
are platform specific tools available which will interpret the
hex addresses for you. The stack walkback code is, of course,
very, very platform specific, but it's rather straightforward on
Intel architecture, and g++ has an extention in its runtime that
you can use with it, so those two platforms are easy.
I read on a web page that replacing global placement new is
illegal. Is it true ?

I think so. It's not listed among the functions you can
replace. (Note too that the replacement functions are NOT
allowed to be inline. This is to ensure that even library code
compiled elsewhere will get the replacement.)
 
L

Lagarde Sébastien

thanks for the tips, I finally achieve my goal with the TLS tips suggested
before.
Thanks you all.

"James Kanze" <[email protected]> a écrit dans le message de
(e-mail address removed)...
I write code to debug new call with following macro:
#define new (MemoryManager::Get().setOwner (__FILE__, __LINE__,
_FUNCTION-),
FALSE) ? NULL : new

[...]
The problem is with placement new, : I don't want to debug
placement new, this is not required, but as my macro is there
I enter in SetOwner, so in the critical section but never
leave...
So to resolve the problem I wrote my own version of placement new:
inline void* __cdecl operator new[](size_t, void* anywhere)
{
leaveCriticalSection();
return anywhere;
}
but my version of placement news seems to never been call and I block in
critical section.

If operator new is inline, then the original version has already
been compiled into the library code.

Formally, using #define to define a keyword is undefined
behavior if you include any standard header. Practically, I
wouldn't be a bit surprised if it didn't cause problems if you
do it before including the standard headers: all it takes is for
a template to be used in two different translation units.

The usual solution here is to write system specific code to do a
stack walkback in the debugging operator new. This only gives
you a hex dump of the stack, to begin with, but it's not as if
you need to use the information that often, and usually, there
are platform specific tools available which will interpret the
hex addresses for you. The stack walkback code is, of course,
very, very platform specific, but it's rather straightforward on
Intel architecture, and g++ has an extention in its runtime that
you can use with it, so those two platforms are easy.
I read on a web page that replacing global placement new is
illegal. Is it true ?

I think so. It's not listed among the functions you can
replace. (Note too that the replacement functions are NOT
allowed to be inline. This is to ensure that even library code
compiled elsewhere will get the replacement.)
 

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

Forum statistics

Threads
473,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top