- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Actually I'm using embree with custom geometry management. The geometry provided by some random user. For each step of my software I want to know and manage error if some occurs, to give user correct information.
At the begining I was using embree 2.4
My problem was, when I have a model with a lot of triangle for my system, my software was just exit with no prompt, no catch, no exception when I call rtcCommit.
After some digging, I find that embree 2.10 resolve my problem. But after testing with the provided dll with TBB, or a compiled version with TBB and an other without I still have the same issue.
rtcCommit throw an exception that i can catch, but i still have embree thread running that have issue (Access violation writing location,). So I can't really do a clean error management and my program can't continue, because crash occurs outside my main thread.
Is there a way to check memory usage before a rtcCommit and avoiding unnecessary job to embree? or a possibility to generate accel structure with my main thread.. Or another solution that I can't guess fopr now ? In this section of my code, I d'ont need strong performance, because I only use static scene and this is done once.
L.17 call of function where the bug appear
L 92 wild crash appear. Obvsiously I've tested this code with a lot of different geometry of different size, but this one is really big.
Thanks for any advice/hint
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Lagarde,
I tried creating a large scene under Linux and also see the application to get killed during rtcCommit (./viewer -triangle-sphere 5000). I could not find a way to avoid this. In case the memory allocations (like new or mmap) fail, Embree properly returns an error code. However, if the OS decides to kill the application due to too much memory usage there is nothing we can do about.
rtcCommit should not throw any exception, could you please verify and tell us which exception it is. rtcCommit sets an error code that you can query using the rtcDeviceGetError function.
You can track the memory consumption of Embree during rtcCommit. Therefore register a memory monitor callback function (see here embree.github.com/api.html). Inside this function you can accumulate the total memory consumption of Embree and terminate the BVH build if too much memory is used. You can also check the total memory consumption of your application in that callback and terminate if some limits are reached.
In case this helps, you can also force rtcCommit to only use one thread. Therefore call rtcNewDevice("thread=1") or configure TBB to use only one thread in your application (see Limiting Number of Build Thread section of embree.github.com/api.html).
Regards,
Sven
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sven,
Thanks you for your answer.
So I did some more digging on the error.
1. rtcCommit and exception throw
Visual Studio, my debugger, catch an "Access violation writing".
I have Multiple error like this before reaching the catch(...) block
of my program (l96 of the pastebin)
This error occur at first, in a embree internal thread and after some step forward(thanks to the debugger),
the main thread detect error in catch block.
When I reach this catch block, I add this lines (not present in the pastbin):
embreeError = rtcDeviceGetError(NULL);
if (embreeError != RTC_NO_ERROR)
{
LoggerUtils::PushLog(LOGTYPE_ERROR, "rtcNewDevice failed.", VPLOGL_PRETTY_FUNCTION);
throw std::exception("embree error");
}
else
{
embreeError = rtcDeviceGetError(_embreeDevice);
if (embreeError != RTC_NO_ERROR)
{
LoggerUtils::PushLog(LOGTYPE_ERROR, "rtcNewDevice failed.", VPLOGL_PRETTY_FUNCTION);
throw std::exception("embree error");
}
}
but embreeError == RTC_NO_ERROR.
2. Exit of the application
In this section I'm guessing because of a Fix found in section 3.
The application exit because, I can't catch and manage an error that occur
in a thread that I don't manipulate. Here, in the internal embree thread.
So because thread is hanging, OS kill the application ?
In my case application doesn't exit, I'm stuck in the debugger.
When I was using embree 2.4 application exit and can't do anything with the debugger.
3. The Fix
If I replace rtcCommit(_embreeScene) by rtcCommitThread(_embreeScene, 0, 1),
the error occur, and I still reach the catch (...) block. However my debugger
isn't looping anymore in embree internal thread, and the program
can continue.
I think this works because rtcCommitThread, use the caller thread to do it's job.
So there isn't any thread stuck.
This fix is fine for me now, but I'm a bit disappointed. What do you think of it?
Regards
Mathieu
---------------- Information ----------------
Embree 2.10 compiled in release mode
32 bit
TBB off
ISPC off
My program is compiled in debug mode.
32 bit
My machine is on
win7 64bit
I have 16 GB of ram
Program crash when reaching about 1.5-1.7 GB
======================================================
Original buggy Method
Parameter:
_embreeDevice = rtcNewDevice("thread=1"); //L8 of pastebin
use of rtcCommit(_embreeScene);
stacktrace when catch(...) occurs:
--------------- embree thread ---------------
stack trace:
> embree.dll!rtcDebug() + 0x6aa48 bytes
[Frames below may be incorrect and/or missing, no symbols loaded for embree.dll]
embree.dll!rtcDebug() + 0x6526e bytes
embree.dll!rtcDebug() + 0x6c7ed bytes
embree.dll!embree::TaskScheduler::TaskQueue::execute_local() + 0x3c bytes
embree.dll!embree::TaskScheduler::threadIndex() + 0x19f bytes
embree.dll!embree::TaskScheduler::threadIndex() + 0x345 bytes
embree.dll!embree::TaskScheduler::threadIndex() + 0x3f bytes
embree.dll!rtcDebug() + 0x75a3a2 bytes
kernel32.dll!BaseThreadInitThunk() + 0x12 bytes
ntdll.dll!RtlInitializeExceptionChain() + 0x63 bytes
ntdll.dll!RtlInitializeExceptionChain() + 0x36 bytes
disassembly:
not really readable for me but can't step foward with the debugger
Message provided by Visual Studio:
Exception thrown at 0x04fc4928 (embree.dll) in CLEAViewer.exe: 0xC0000005: Access violation writing location 0x00000000.
If there is a handler for this exception, the program may be safely continued.
--------------- My program thread ---------------
stack trace:
embree.dll!rtcDebug() + 0x6aa48 bytes
[Frames below may be incorrect and/or missing, no symbols loaded for embree.dll]
embree.dll!rtcDebug() + 0x6526e bytes
embree.dll!rtcDebug() + 0x6c7ed bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::TaskQueue::execute_local() + 0x3c bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x13c bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!rtcDebug() + 0x54ea8 bytes
embree.dll!rtcDebug() + 0xdc64b bytes
embree.dll!rtcDebug() + 0x77e5b bytes
embree.dll!ISPCSync() + 0x127d0 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!ISPCSync() + 0x12550 bytes
embree.dll!rtcUpdateBuffer() + 0x1d5e bytes
embree.dll!rtcDebug() + 0x128b bytes
embree.dll!embree::TaskScheduler::TaskQueue::execute_local() + 0x3c bytes
embree.dll!rtcUpdateBuffer() + 0xd5d bytes
embree.dll!rtcUpdateBuffer() + 0x1c68 bytes
embree.dll!rtcCommit() + 0xb2 bytes
> CLEARenderLib.dll!CPUScene::GenerateEmbreeScene() Line 289 + 0xd bytes C++
CLEARenderLib.dll!CPUScene::Initialize() Line 69 + 0x8 bytes C++
CLEARenderLib.dll!ViewManager::PostInitialize() Line 120 + 0x1a bytes C++
CLEARenderLib.dll!WindowManager::Initialize() Line 104 + 0xb bytes C++
CLEARenderLib.dll!OutputEngine::Initialize() Line 20 + 0x12 bytes C++
CLEARenderLib.dll!CleaEngine::Initialize() Line 47 + 0x2b bytes C++
[External Code]
CLEARenderLib.dll!CLEARendererLib::Engine::INITIALISE_ENGINE_DATA() Line 81 + 0x22 bytes C++
CLEAViewer.exe!JSONLoadTest(std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >* path, bool printConfiguration) Line 102 + 0x15 bytes C++
CLEAViewer.exe!main(array<System::String^> ^ args) Line 239 + 0x2b bytes C++
CLEAViewer.exe!mainCRTStartupStrArray(array<System::String^> ^ arguments) Line 301 + 0x9 bytes C++
disassembly:
//rtcCommitThread(_embreeScene, 0, 1);
rtcCommit(_embreeScene);
0FB2C81C mov eax,dword ptr [ebp-18h]
0FB2C81F mov ecx,dword ptr [eax+4Ch]
0FB2C822 push ecx
0FB2C823 call dword ptr [__imp__rtcCommit (0FC71608h)]
0FB2C829 add esp,4
Message provided by Visual Studio:
Exception thrown at 0x04fc4928 (embree.dll) in CLEAViewer.exe: 0xC0000005: Access violation writing location 0x0170fee0.
If there is a handler for this exception, the program may be safely continued.
======================================================
Hacking Method
Parameter:
_embreeDevice = rtcNewDevice(NULL); //L8 of pastebin
use of rtcCommitThread(_embreeScene, 0, 1); //L92 of pastebin
stacktrace when catch(...) occurs:
embree.dll!rtcDebug() + 0x6aa48 bytes
[Frames below may be incorrect and/or missing, no symbols loaded for embree.dll]
embree.dll!rtcDebug() + 0x6526e bytes
embree.dll!rtcDebug() + 0x6c7ed bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!rtcDebug() + 0x54ea8 bytes
embree.dll!rtcDebug() + 0xdc64b bytes
embree.dll!rtcDebug() + 0x77e5b bytes
embree.dll!ISPCSync() + 0x127d0 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!embree::TaskScheduler::Task::run() + 0x86 bytes
embree.dll!embree::TaskScheduler::wait() + 0x5e bytes
embree.dll!ISPCSync() + 0x12550 bytes
embree.dll!rtcUpdateBuffer() + 0x1d5e bytes
embree.dll!rtcDebug() + 0x128b bytes
embree.dll!embree::TaskScheduler::TaskQueue::execute_local() + 0x3c bytes
embree.dll!rtcUpdateBuffer() + 0xd5d bytes
embree.dll!rtcUpdateBuffer() + 0x1c68 bytes
embree.dll!rtcCommitThread() + 0x141 bytes
> CLEARenderLib.dll!CPUScene::GenerateEmbreeScene() Line 288 + 0x11 bytes C++
CLEARenderLib.dll!CPUScene::Initialize() Line 69 + 0x8 bytes C++
CLEARenderLib.dll!ViewManager::PostInitialize() Line 120 + 0x1a bytes C++
CLEARenderLib.dll!WindowManager::Initialize() Line 104 + 0xb bytes C++
CLEARenderLib.dll!OutputEngine::Initialize() Line 20 + 0x12 bytes C++
CLEARenderLib.dll!CleaEngine::Initialize() Line 47 + 0x2b bytes C++
[External Code]
CLEARenderLib.dll!CLEARendererLib::Engine::INITIALISE_ENGINE_DATA() Line 81 + 0x22 bytes C++
CLEAViewer.exe!JSONLoadTest(std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >* path, bool printConfiguration) Line 102 + 0x15 bytes C++
CLEAViewer.exe!main(array<System::String^> ^ args) Line 239 + 0x2b bytes C++
CLEAViewer.exe!mainCRTStartupStrArray(array<System::String^> ^ arguments) Line 301 + 0x9 bytes C++
disassembly:
try
{
04B6C814 mov dword ptr [ebp-4],0
04B6C81B wait
rtcCommitThread(_embreeScene, 0, 1);
04B6C81C push 1
04B6C81E push 0
04B6C820 mov eax,dword ptr [ebp-18h]
04B6C823 mov ecx,dword ptr [eax+4Ch]
04B6C826 push ecx
04B6C827 call dword ptr [__imp__rtcCommitThread (4CB160Ch)]
04B6C82D add esp,0Ch
//rtcCommit(_embreeScene);
Message provided by Visual Studio:
Exception thrown at 0x05084928 (embree.dll) in CLEAViewer.exe: 0xC0000005: Access violation writing location 0x0452fce0.
If there is a handler for this exception, the program may be safely continued.
-------
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mathieu,
I could reproduce and locate the issue under Windows 32 bit. The problem is that we did not check if _mm_malloc returned nullptr when failing. Please replace the alignedMalloc function in common/sys/alloc.cpp with:
void* alignedMalloc(size_t size, size_t align)
{
assert((align & (align-1)) == 0);
void* ptr = _mm_malloc(size,align);
if (size != 0 && ptr == nullptr)
throw std::bad_alloc();
return ptr;
}
We will have this fixed in the next release.
Sven
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sven,
Thanks you for your answer and your time. I have modified the void *alignedMalloc, all works fine.
Thanks again !
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page