none
Problem on using NUI in dll plugin, thread deadlock on exit RRS feed

  • Question

  • Hellow, I am trying to write on C++ plugin dll with NUI, all goes ok (NUI init, shutdown etc.) until freeing library (unloading plugin). One of the internal threads in KINECTSQM.dll!513e37a8() are locked on sqmapi.dll!_SqmWaitForUploadComplete@8() + 0x5a. Any suggestion, what I am doing wrong?

    And one more question, is it normal what after exiting NUI kinect's IR transmitter are always enabled(red blured point in left standalone kinect eye)?

    Wednesday, July 20, 2011 9:17 AM

All replies

  • Are you able to get the callstacks for the two threads that are deadlocking with each other? If you can get that information and post it here, I should be able to help you some more.

    thanks,
    Eddy


    I'm here to help
    Wednesday, July 20, 2011 11:00 PM
  • The problem is in sqm(Windows Customer Experience Improvement Program), kinect SDK collects some info and try to send it on exit and i don't know why this sending deadlocks thread...
    Thursday, July 21, 2011 9:09 AM
  • Does this happen within a call to the DllMain function of your Dll? It is not safe to call NuiShutdown within DllMain of a Dll. If that's what you're doing, I would recommend that your Dll export "Initialize" and "Uninitialize" functions (a fairly standard Dll programming pattern), and you call NuiInitialize and NuiShutdown in those functions, respectively.

    Does this make sense?
    Eddy


    I'm here to help
    Thursday, July 21, 2011 7:46 PM
  • No, i have init and shutdown functions exported, NuiShutdown successfully returns. deadlock happens on FreeLibrary in parent exe.
    Sunday, July 24, 2011 11:10 AM
  • Which two threads are the ones deadlocking, though? There is one kinect internal thread (A) that is calling into sqmapi.dll!_SqmWaitForUploadComplete@8() + 0x5a and you say there's another thread (B) in parent executable that is calling FreeLibrary? Are you saying that thread B is also calling into SQM API and waiting for lock? Would it be possible for you to share the full callstack (From Debug|Windows|Call Stack option in the menu) from the thread calling FreeLibrary, or even the full call stack with your personal private functions removed (as ...)?

    Thanks,
    Eddy


    I'm here to help
    Tuesday, July 26, 2011 12:52 AM
  • Hello Eddy

    I have the same problem. Can you help me?

    I load kinect library in plugin. When I close my application it can't shutdown.

    Thursday, September 15, 2011 6:59 PM
  • I'm experiencing the same issues too and it's very annoying. Trying to use efficiently the Kinect SDK with 3DVIA Virtools by the way of plugin, our application can't close properly. If someone find a solution to that problem, I'm very interested
    Monday, September 19, 2011 11:14 AM
  • Hello, Eddy. I have written a Max external which exposes the KinectSDK. I believe I am experiencing a related (perhaps the same) problem as in this thread.

    If I even NuiInitialize(), then Max.exe will never close. Even if I call NuiShutdown(), Max.exe will still not close. I have isolated it to be only due to using the Kinect SDK. When I run Process Monitor against it, I see at the end of the events for Max.exe the following. There are no events after this...and max.exe hasn't fully exited. It is still a running process.

    15:05:04.3729272 Max.exe 7476 CreateFile C:\Users\Dale Phurrough NAME COLLISION Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, Write, AllocationSize: 0 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3733181 Max.exe 7476 CreateFile C:\Users\Dale Phurrough\AppData\Roaming NAME COLLISION Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, Write, AllocationSize: 0 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3765726 Max.exe 7476 CreateFile C:\Users\Dale Phurrough NAME COLLISION Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, Write, AllocationSize: 0 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3769593 Max.exe 7476 CreateFile C:\Users\Dale Phurrough\AppData\Roaming NAME COLLISION Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, Write, AllocationSize: 0 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3811082 Max.exe 7476 CreateFile C:\Users\Dale Phurrough NAME COLLISION Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, Write, AllocationSize: 0 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3815030 Max.exe 7476 CreateFile C:\Users\Dale Phurrough\AppData\Roaming NAME COLLISION Desired Access: Read Data/List Directory, Synchronize, Disposition: Create, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: N, ShareMode: Read, Write, AllocationSize: 0 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3925634 Max.exe 7476 CreateFile C:\Users\Dale Phurrough\AppData\Local\Temp\MSRKinect00.sqm NAME NOT FOUND Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3970297 Max.exe 7476 RegQueryValue HKLM\SOFTWARE\Microsoft\SQMClient\UploadDisableFlag NAME NOT FOUND Length: 144 "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3972671 Max.exe 7476 CreateFile C:\Program Files (x86)\Cycling '74\Max 5.0\SensApi.dll NAME NOT FOUND Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3974330 Max.exe 7476 CreateFile C:\Program Files (x86)\Cycling '74\Max 5.0\support\SensApi.dll NAME NOT FOUND Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.3979455 Max.exe 7476 CreateFileMapping C:\Windows\SysWOW64\SensApi.dll FILE LOCKED WITH ONLY READERS SyncType: SyncTypeCreateSection, PageProtection: "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"

    15:05:04.4007539 Max.exe 7476 QueryDirectory C:\Users\Dale Phurrough\AppData\Local\Temp NO MORE FILES "C:\PROGRA~2\CYCLIN~1\MAX5~1.0\Max.exe" "C:\Users\Dale Phurrough\Documents\Visual Studio 2010\Projects\kinect\dp.kinect\bin\dpkinect.maxpat"


    --Dale
    Saturday, September 24, 2011 1:23 PM
  • Hi Eddy,

     

    Did you find a solution for this problem?

     

    I have some small code for you to show the problem !

    Possible to send it to you ?

     

    Kind regards

    almidi

     

    Monday, September 26, 2011 10:21 AM
  • almidi,

    sure, paste code sample in this thread.

    Thanks!

    Eddy


    I'm here to help
    Wednesday, September 28, 2011 8:19 PM
  • Hi Eddy,

     

    I have the exact same issue... No hope in sight :(

    Any ideas how this can be solved? I am writing a plugin so I do not have access to the host application.

     

    Thanks,

    Saar

    Wednesday, November 23, 2011 9:55 PM
  • Hello - I'm also creating a plugin which hangs the host application on exit.  I created a barebones example which only implements the initialization and uninitialization of the Kinect.  The plugin - an Adobe Director XTRA, a form of DLL - is also stripped down and implements the scripting interface to create an instance - new(), init() and uninit().  So here are some sequence of events:

    1. Create new plugin instance     (success)
    2. Dispose of instance                  (success) 
    3. Quit application                        (successfully quit) 

    and then to illustrate the hung application issue:

    1. Create new plugin instance     (success)
    2. Initialize Kinect     (Nui_Init)     (success)
    3. Uninitialize Kinect (Nui_UnInit) (success) (red IR light gone and result codes OK)
    4. Dispose of instance                  (success)
    5. Quit application                         (hung application) 

    In the actual plugin I'm working on, the Kinect SDK seems to be working in every thing that I've used it for, so far, except a graceful shutdown.

    Using SysInternals 'Process Explorer' I observe the following information about a sample program test harness and the barebones plugin's interaction with it:

    1. At startup time, I have two threads running in the program
    2. Calling the Nui_Init()  function, 12 new threads are created
    3. Calling the Nui_Uninit() function,  I'm left with 6 threads, 4 more than expected, all have a call stack like below:

     

     ntdll.dll!KiFastSystemCallRet
     kernel32.dll!BaseThreadInitThunk+0x12
     ntdll.dll!RtlInitializeExceptionChain+0xef
     ntdll.dll!RtlInitializeExceptionChain+0xc2

     4. Quitting the test harness program, a new thread is started with an entry point of:
            sqmapi.dll!SqmGetEscalationRuleStatus+0xf1d4
    5.  At this point, the program shutdown is hung, if I kill the Sqmapi thread with Process Explorer, the test harness program will finish shutting down. 

    I can make the test harness program available if useful.  (example.exe - 2.6 MB)

     

    Since code was asked for earlier in this thread, I'll paste the barebones examples of the Kinect-oriented cpp/h files.  As you can see, this is a stripped down example out of the skeleton/c++ code.

    Thank you for any insight into this issue.

    -Steve

    /*--<NuiImpl.h>-------------*/
    #pragma once
    #include "MSR_NuiApi.h"
    class NuiImpl
    {
    public:

      NuiImpl(void);
      ~NuiImpl(void);
    HRESULT Nui_Init(void);
    void Nui_UnInit(void);
    void Nui_Zero(void);
    private:
    INuiInstance* m_pNuiInstance;
    BSTR m_instanceId;
    };
    /*------------------------------*/

     

    /*--<NuiImpl.cpp>---------*/
    #include "stdafx.h"
    #include "NuiImpl.h"
    #include <MMSystem.h>
     
    NuiImpl::NuiImpl(void)
    {
    }

     

    NuiImpl::~NuiImpl(void)
    {
    NuiImpl::Nui_UnInit();
    }

    HRESULT NuiImpl::Nui_Init(void)
    {
    HRESULT hr;
    if (!m_pNuiInstance)
    {
    HRESULT hr = MSR_NuiCreateInstanceByIndex(0, &m_pNuiInstance);
    if (FAILED(hr)){
    return hr;
    }
    if (m_instanceId){
    ::SysFreeString(m_instanceId);
    }
    m_instanceId = m_pNuiInstance->NuiInstanceName();
    }
    hr = m_pNuiInstance->NuiInitialize( NUI_INITIALIZE_FLAG_USES_DEPTH_AND_PLAYER_INDEX |
                                                                     NUI_INITIALIZE_FLAG_USES_COLOR |
                                                                     NUI_INITIALIZE_FLAG_USES_SKELETON);

    if (FAILED(hr)){
    return hr;
    }
    return hr;
    }

    void NuiImpl::Nui_UnInit(void)
    {
    if (m_pNuiInstance){
            m_pNuiInstance->NuiShutdown( );
    MSR_NuiDestroyInstance(m_pNuiInstance);
    }
    if (m_instanceId){
    ::SysFreeString(m_instanceId);
    }
    Nui_Zero();
    }

    void NuiImpl::Nui_Zero(void)
    {
    m_pNuiInstance = NULL;
    }

    /*------------------------------*/

     

     


    • Edited by shagenlo Friday, November 25, 2011 8:20 PM
    Friday, November 25, 2011 8:17 PM
  • I have the same problem when I uninit kinect on DLL_PROCESS_DETACH. When I uninit kinect before DLL_PROCESS_DETACH was call, everything is good.
    Saturday, December 3, 2011 1:06 PM
  • I have the same problem when I uninit kinect on DLL_PROCESS_DETACH. When I uninit kinect before DLL_PROCESS_DETACH was call, everything is good.

     

    Hi Alexey,

    When you uninit BEFORE DLL_PROCESS_DETACH, does your program closes gracefully?

    I can see that no matter when I uninit Kinect (i.e. Shutdown + destroy instance), my application never closes.

     

    Thanks,

    Saar

     

     

    Saturday, December 3, 2011 11:29 PM
  • Saar wrote:
    >>I can see that no matter when I uninit Kinect (i.e. Shutdown + destroy instance), my application never closes.

    I agree with the above sentiment, I have a minimal test implementation to try to isolate the problem.  My plugin has script commands for initialization and teardown which are separated in both lengths of time (seconds to minutes) and call stack from actual shutdown and detach of the controlling DLL.  In this further minimized test implementation, I have the NUI class boiled down to this very small implementation:

    #include "stdafx.h"
    #include "NuiImpl.h"
    #include <MMSystem.h>
    
    HRESULT NuiImpl::Nui_Init(void)
    {
    	HRESULT hr;
    	hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR);
    	return hr;
    }
    
    void NuiImpl::Nui_UnInit(void)
    {
    	NuiShutdown();
    }
    

    Upon shutdown of this test harness loaded into the plugin host, I do see the thread attempting to use sqmapi.dll in Process Explorer with the thread: sqmapi.dll!SqmGetEscalationRuleStatus+0xf1d4

    If I kill that thread with Process Explorer, the program then exits.

    I'd be happy to provide any further information if anyone has any ideas.  I'm very curious how other DLL implementations are not getting caught by this, and wonder if it is a red herring and more to do with the OS, or patch level or something outside of the Kinect SDK domain.

     

    • Proposed as answer by Max Wheeler Tuesday, September 9, 2014 8:01 PM
    Sunday, December 4, 2011 1:40 AM

  • I agree with the above sentiment, I have a minimal test implementation to try to isolate the problem.  My plugin has script commands for initialization and teardown which are separated in both lengths of time (seconds to minutes) and call stack from actual shutdown and detach of the controlling DLL.  In this further minimized test implementation, I have the NUI class boiled down to this very small implementation:

     

    #include "stdafx.h"
    #include "NuiImpl.h"
    #include <MMSystem.h>
    
    HRESULT NuiImpl::Nui_Init(void)
    {
    	HRESULT hr;
    	hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_COLOR);
    	return hr;
    }
    
    void NuiImpl::Nui_UnInit(void)
    {
    	NuiShutdown();
    }
    

    Upon shutdown of this test harness loaded into the plugin host, I do see the thread attempting to use sqmapi.dll in Process Explorer with the thread: sqmapi.dll!SqmGetEscalationRuleStatus+0xf1d4

     

    If I kill that thread with Process Explorer, the program then exits.

    I'd be happy to provide any further information if anyone has any ideas.  I'm very curious how other DLL implementations are not getting caught by this, and wonder if it is a red herring and more to do with the OS, or patch level or something outside of the Kinect SDK domain.

     

     

     

     

    So... Since it doesn't look like MS is willing to help (Or even respond) on this issue, could you suggest a workaround until this problem is fixed?

    Perhaps killing the offending thread before shutting down, is that possible?

     

    Thanks again,

    Saar

    Friday, December 9, 2011 9:31 PM
  • I was having the same problem and I've just found out myself that the process will exit gracefully if the DLL is compiled with CLR support.
    Thursday, December 22, 2011 3:38 PM
  • I can't compile with CLR support... (My code is unmanaged and I'm using OpenMP).

     

    Are you sure that CLR support helps?

     

    Thanks again.

    Friday, December 23, 2011 9:06 PM