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

[CRASH] Visual Studio tbbmalloc_proxy implementation bugs

e4lam
Beginner
1,077 Views

Hi,

Found some bugs in the Visual Studio tbbmalloc_proxy implementation. These bugs should also exist for VS2008 (or later), but I've only tested this in VS2012.

  1. _aligned_msize() is not hooked. When this is called, the standard “_aligned_mize” is triggered, causing a crash since the block has been allocated by tbb and not by the standard allocator.
  2. _aligned_malloc() is hooked but a 0-alignment causes NULL to be returned, contrary to the (bad) CRT behaviour. The CRT behaviour is to accept 0 but silently use sizeof(void*)-alignment. While I agree with the behaviour of scalable_aligned_malloc(), the hooked version should probably emulate CRT bugs.

Thanks!

0 Kudos
8 Replies
Vladimir_P_1234567890
1,077 Views

first bugs against malloc_proxy:)

We'll take a look, thanks
--Vladimir

0 Kudos
e4lam
Beginner
1,077 Views

Yes, other than the scalable_msize() bug that I independently ran into with other users 3 yrs ago :)

0 Kudos
Vladimir_P_1234567890
1,077 Views

added to update 3  (tbb42_20140122oss) release.

--Vladimir

0 Kudos
Simon_G_
Beginner
1,077 Views

I'm getting crashes using when using TBB42_20140122oss with Qt5.2.1 and VS2012.

It's always this:
msvcrt.dll!_endthreadex():

         tbbmalloc_debug.dll!rml::internal::safer_dereference(const rml::internal::BackRefIdx * ptr) Line 2334        C++

         tbbmalloc_debug.dll!rml::internal::isSmallObject(void * ptr) Line 2363         C++

         tbbmalloc_debug.dll!safer_scalable_free(void * object, void (void *) * original_free) Line 2765     C++

         tbbmalloc_proxy_debug.dll!safer_scalable_free_msvcr110(void * ptr) Line 327    C++

 msvcr110.dll!_freefls(void * data) Line 436        C

         ntdll.dll!RtlProcessFlsData‑()     Unknown

         ntdll.dll!LdrShutdownThread‑()     Unknown

         ntdll.dll!RtlExitUserThread‑()     Unknown

         msvcrt.dll!_endthreadex‑() Unknown

         msvcrt.dll!_endthreadex‑() Unknown

         msvcrt.dll!_endthreadex‑() Unknown

         kernel32.dll!BaseThreadInitThunk‑()         Unknown

         ntdll.dll!RtlUserThreadStart‑()    Unknown

My code seems to be doing fairly innocuous stuff, it could be Qt, but doesn't crash when tbb_malloc_proxy.h isn't included - my main thread is deep in the windows stack:

    ntdll.dll!NtWaitForSingleObject‑()    Unknown
     KernelBase.dll!WaitForSingleObjectEx‑()    Unknown
     duser.dll!000007fefb950eae()    Unknown
     duser.dll!000007fefb94b50c()    Unknown
     duser.dll!000007fefb94acae()    Unknown
     duser.dll!000007fefb94ac0f()    Unknown
     dui70.dll!000007fefb9afee7()    Unknown
     ExplorerFrame.dll!000007fef81baa3f()    Unknown
     ExplorerFrame.dll!000007fef81ba938()    Unknown
     ExplorerFrame.dll!000007fef81ba792()    Unknown
     shell32.dll!000007fefda7c07a()    Unknown
     shell32.dll!000007fefda141ff()    Unknown
     comdlg32.dll!CFileOpenSave::_OnDestroyDialog(void)    Unknown
     comdlg32.dll!CFileOpenSave::s_OpenSaveDlgProc(struct HWND__ *,unsigned int,unsigned __int64,__int64)    Unknown
     user32.dll!UserCallDlgProcCheckWow‑()    Unknown
     user32.dll!DefDlgProcWorker‑()    Unknown
     user32.dll!DefDlgProcW‑()    Unknown
     user32.dll!UserCallWinProcCheckWow‑()    Unknown
     user32.dll!DispatchClientMessage‑()    Unknown
     user32.dll!__fnDWORD‑()    Unknown
     ntdll.dll!KiUserCallbackDispatcherContinue‑()    Unknown
     user32.dll!ZwUserDestroyWindow‑()    Unknown
     user32.dll!DialogBox2‑()    Unknown
     user32.dll!InternalDialogBox‑()    Unknown
     user32.dll!DialogBoxIndirectParamAorW‑()    Unknown
     user32.dll!DialogBoxIndirectParamW‑()    Unknown
     comdlg32.dll!CFileOpenSave::Show(struct HWND__ *)    Unknown
     qwindowsd.dll!QWindowsNativeFileDialogBase::exec(HWND__ * owner) Line 968    C++
     qwindowsd.dll!QWindowsDialogHelperBase:exec() Line 612    C++
     Qt5Widgetsd.dll!QDialog::exec() Line 525    C++
     Qt5Widgetsd.dll!QFileDialog::getOpenFileName(QWidget * parent, const QString & caption, const QString & dir, const QString & filter, QString * selectedFilter, ... Line 1792    C++

 

I do use some tasking from QtConcurrent, so my only thought is that perhaps the TBB thread pooling and QtConcurrent pooling are treading on each others toes. There are tons of threads when it crashes, but everything is on some variant of WaitingForSingleObject.

The only other thing I can think of is that I use a QWebView (an embedded Webkit instance) and who the frig knows how it handles threading or interacts with TBB.

All I know is that occasionally, just occasionally, it'll crash as above and I have no idea why. Any help appreciated.

 

PS: This message "Your submission contains invalid characters and will not be accepted." is driving me insane. What is wrong? Who knows? Just a character somewhere. Thank you. I wish compilers did this too. It's so helpful.

0 Kudos
Vladimir_P_1234567890
1,077 Views

Hello Simon,

is this crash or access violation exception in the debugger? In the code this one line is covered by __try{}_except{} block. The idea is that there might be access violation exception but it should be handled properly.

--Vladimir

0 Kudos
Simon_G_
Beginner
1,077 Views

In the debugger:
0xC0000005: Access violation reading location 0x000000000D26806C.

I can continue in the debugger and it seems to be OK. Is this really a case of VS jumping in too early and not letting the handler catch it? 

0 Kudos
Vladimir_P_1234567890
1,077 Views

Exactly, debugger catches such exceptions before passes them to handler.
This is the code. it checks if we can read this memory:) If we can read this memory we can check then whether memory was allocated by tbbmalloc or not.

[cpp]

__try {

    id = *ptr; // <--this is "Line 2334"

    } __except( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION?

        EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ) {

        id = BackRefIdx();

    }[/cpp]

--Vladimir

0 Kudos
e4lam
Beginner
1,077 Views

e4lam wrote:
_aligned_malloc() is hooked but a 0-alignment causes NULL to be returned, contrary to the (bad) CRT behaviour. The CRT behaviour is to accept 0 but silently use sizeof(void*)-alignment. While I agree with the behaviour of scalable_aligned_malloc(), the hooked version should probably emulate CRT bugs.

As a heads up here, Microsoft has fixed this bug in the CRT for the upcoming Visual Studio 2014.

http://blogs.msdn.com/b/vcblog/archive/2014/06/18/crt-features-fixes-and-breaking-changes-in-visual-studio-14-ctp1.aspx

Aligned Allocation Functions: In previous versions, the aligned allocation functions (_aligned_malloc, _aligned_offset_malloc, etc.) would silently accept requests for a block with an alignment of 0. The documentation requires that the requested alignment be a power of two, which zero is not. This has been fixed, and a requested alignment of 0 is now treated as an invalid parameter (Connect #809604).

So we'll need to have a special case for the VS2014 CRT.

Thanks!

0 Kudos
Reply