Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.

Calling scalable_malloc directly

Long_Nguyen
Beginner
972 Views

Hello,

Is it possible to call scalable_malloc and scalable_free directly from tbbmalloc.dll instead of going through tbbmalloc_proxy.dll and the memory allocation function replacement stuff?

The reason I am asking is that I am running into the same issue in this post: http://software.intel.com/en-us/forums/showthread.php?t=70847&o=d&s=lr

My program crashes on exit, always in the doexit function (crt0dat.c):

/* cache the function to call. */
function_to_call = (_PVFV)_decode_pointer(*onexitend);
/* mark the function pointer as visited. */
*onexitend = (_PVFV)_encoded_null();
/* call the function, which can eventually change __onexitbegin and __onexitend */
(*function_to_call)();<=== ACCESS VIOLATION HERE!

I have a lot of static variables in my application, residing in many namespaces. Here is the TBB package that I used (I think it's 2.2 update 3):tbb22_013_win.exe

Package ID: w_tbb_pu_2.2.013

Version on tbbmalloc.dll:2.2.2010.204

TBB: VERSION 2.2

TBB: INTERFACE VERSION 4003

TBB: BUILD_DATE Thu, 4 Feb 2010 14:23:01 UTC

TBB: BUILD_HOST FXEOWIN16

TBB: BUILD_OS Microsoft Windows [Version 5.2.3790]

TBB: BUILD_CL Microsoft 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86

TBB: BUILD_COMPILER Intel C++ Compiler Professional for applications running on IA-32, Version 11.1 Build 20090903 Package ID: w_cproc_p_11.1.046

TBB: BUILD_TARGET ia32

TBB: BUILD_COMMAND icl /nologo /Qvc9 /MD /O2 /Zi /EHsc /GR /Zc:forScope /Zc:wchar_t /Oy /DDO_ITT_NOTIFY /DUSE_WINTHREAD /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0400 /D__TBB_BUILD=1 /W3 /WX

TBB: TBB_USE_DEBUG undefined

TBB: TBB_USE_ASSERT undefined

TBB: DO_ITT_NOTIFY 1

Thanks for you help.

-Long

0 Kudos
7 Replies
RafSchietekat
Valued Contributor III
972 Views
"Is it possible to call scalable_malloc and scalable_free directly from tbbmalloc.dll instead of going through tbbmalloc_proxy.dll and the memory allocation function replacement stuff?"
Yes. You might also try replacing just C++ new/delete.

0 Kudos
Vladimir_P_1234567890
972 Views

yes.

You can either look at implementation of proxy.h and link with tbbmalloc.lib library or use usual LoadLibrary calls.

--Vladimir

0 Kudos
Alexey-Kukanov
Employee
972 Views

> Is it possible to call scalable_malloc and scalable_free directly from tbbmalloc.dll instead of going through tbbmalloc_proxy.dll and the memory allocation function replacement stuff?

Yes :)
Include tbb/scalable_allocator.h, and link with tbbmalloc.lib. Or, as Vladimir suggested, load tbbmalloc.dll dynamically with LoadLibrary, and obtain function pointers with GetProcAddress.

0 Kudos
Vladimir_P_1234567890
972 Views

BTW do you use tbbmalloc_proxy or modified implementaion? tbbmalloc_proxy should work with static variables and should not cause crash).

--Vladimir

0 Kudos
Long_Nguyen
Beginner
972 Views
I did include , link in tbbmalloc.lib, and call
scalable_malloc/scalable_free directly. Therefore bypassing
tbbmalloc_proxy.dll and memory allocation replacement.
We created a simple DLL called kmem.dll. Any client that links with this DLL
will have operators new/delete overridden with those implemented in kmem.dll.
Here is the code:
#pragma once
if defined(KMEM_EXPORT)
#define A_B_C_KMEM_PUBLIC __declspec(dllexport) /* Definition */
#else
#define A_B_C_KMEM_PUBLIC __declspec(dllimport) /* Use */
#endif
namespace A {
namespace B {
namespace C {
namespace Kmem {
A_B_C_KMEM_PUBLIC void* operator new (size_t);
A_B_C_KMEM_PUBLIC void operator delete (void *) throw ();
}}}}
inline void* operator new (size_t size){
return A::B::C::Kmem::operator new (size);
}
inline void operator delete (void * p) throw () {
A::B::C::Kmem::operator delete (p);
}
//#include // Scenario 1: use tbbmalloc_proxy.dll
#include
namespace A {
namespace B {
namespace C {
namespace Kmem {
A_B_C_KMEM_PUBLIC void* operator new (size_t size) {
//return ::operator new(size); // Scenario 1
return scalable_malloc(size);
}
A_B_C_KMEM_PUBLIC void operator delete (void *addr) {
//::operator delete(addr);
if (isRecognized(addr)) // I exposed this function
{
scalable_free(addr);
}
else
{
::operator delete(addr);
}
}
}}}}
In scenario 1 (use tbbmalloc_proxy, allow memory allocation routines
replacement), my app crashes on exit with newer version of tbb. It doesn't
crash on exit with older versions.
In the other scenario where tbbmalloc_proxy is not used and
scalable_malloc/scalable_free are called directly, my app crashes hard
mid-execution (access violation in free.c, function _free_base, line 109,
call to: retval = HeapFree(_crtheap, 0, pBlock);)
Am I doing anything wrong here? Any help/suggestion is greatly appreciated.
-Long
0 Kudos
Vladimir_P_1234567890
972 Views

It would be good to see if scalable_free and "A_B_C_KMEM_PUBLIC void operator delete" are on the stack. it looks that scalable_free is not called there.

--Vladimir

0 Kudos
Long_Nguyen
Beginner
972 Views

I was able to set a break point at scalable_free. What's funny is, the execution goes through both the if and the else clause, like they are not there.

A_B_C_KMEM_PUBLIC void operator delete (void *addr) {

//::operator delete(addr);

if (isRecognized(addr)) // I exposed this function

{ scalable_free(addr); } <-- this gets executed

else

{ ::operator delete(addr); } <-- then this gets executed

}

0 Kudos
Reply