【问题标题】:Mutex creation hangs while using impersonation使用模拟时互斥锁创建挂起
【发布时间】:2016-08-04 03:46:49
【问题描述】:

在测试应用程序时,我遇到了奇怪的行为。一些测试使用模拟来以不同的用户身份运行代码,但它们总是会挂起,永远不会完成。

经过一番调查,问题被缩小到使用互斥锁。最初,我们使用基于MSDN documentation 的自己的模拟代码,但即使使用SimpleImpersonation library,问题仍然存在。 这是重现问题的最小示例:

using (Impersonation.LogonUser(DOMAIN, USER, PASSWORD, LogonType.Interactive))
{
    Console.WriteLine("Impersonated");
    bool mine;
    using (new Mutex(true, "Mutex", out mine))
    {
        if (!mine)
            throw new Exception("Couldn't get mutex");
        Console.WriteLine("Got mutex");
    }
}

Console.WriteLine("Finished");

这永远不会结束,它与互斥体的创建保持一致。 documentation 声明它应该抛出异常或返回一些东西,但没有提到阻塞。

其他一些可能相关也可能不相关的观察结果:

  • 如果我们“冒充”当前用户,它会立即返回
  • 如果我们运行实际应用程序并启动另一个实例作为 不同的用户,一切都按预期工作

可能有一些底层系统资源发生了问题,但我们无法弄清楚。如何使这项工作?

更新:根据 Hans 的评论,我尝试禁用 Windows Defender,但没有帮助。这是它所在位置的堆栈跟踪:

    ntdll.dll!_NtWaitForSingleObject@12()
    KernelBase.dll!_WaitForSingleObjectEx@12()
    mscorlib.ni.dll!719c1867()
    [Frames below may be incorrect and/or missing, native debugger attempting to walk managed call stack]   
    mscorlib.ni.dll!719c1852()
    [Managed to Native Transition]  
    mscorlib.dll!System.Threading.Mutex.CreateMutexHandle(bool initiallyOwned, string name, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES securityAttribute, out Microsoft.Win32.SafeHandles.SafeWaitHandle mutexHandle)
        mscorlib.dll!System.Threading.Mutex.MutexTryCodeHelper.MutexTryCode(object userData)
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    mscorlib.dll!System.Threading.Mutex.CreateMutexWithGuaranteedCleanup(bool initiallyOwned, string name, out bool createdNew, Microsoft.Win32.Win32Native.SECURITY_ATTRIBUTES secAttrs)   
    mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew, System.Security.AccessControl.MutexSecurity mutexSecurity) 
    mscorlib.dll!System.Threading.Mutex.Mutex(bool initiallyOwned, string name, out bool createdNew)    
    MutexImpersonationTest.exe!MutexImpersonationTest.Program.Main(string[] args) Line 16   

【问题讨论】:

  • 很奇怪。 FWIW,如果您没有得到好的答案,最后的解决方法是忘记 .net 类并使用 P/Invoke 直接调用 Win32 API。

标签: c# .net winapi mutex impersonation


【解决方案1】:

看起来获取 Mutex 的代码陷入了无限循环,在我的测试中,它在对 new Mutex(...) 的调用中将一个核心固定为 100%。

原因似乎是框架代码首先尝试调用 Win32 CreateMutex,如果失败并出现“拒绝访问”错误,则尝试调用 OpenMutex。如果 OpenMutex 调用失败并显示互斥锁不存在的错误,它会再次重复整个过程,因此如果互斥锁不存在,则会陷入无限循环。

根据CreateMutex documentation,这基本上是正确的方法,但似乎并没有考虑到初始CreateMutex 失败并由于权限而不是拒绝访问的情况在现有的互斥体上。

当我尝试它时似乎确实有效的一件事是在互斥锁名称前加上“Global\”,希望这对您来说是一个合适的解决方法。

【讨论】:

  • 确实可以像这样创建全局互斥锁,但这会限制所有用户会话中的实例,这是行为的巨大变化......
  • 不错,while(true) 代码is here
  • @MártonMolnár 如果您想要一个特定于会话的互斥锁,您似乎有几个选择 - 您可以在模拟之前创建互斥锁 并将其权限设置为允许冒充用户访问它,或使用“Global\”前缀,但将会话 ID (Process.GetCurrentProcess().SessionId) 合并到互斥锁的名称中,从而在全局命名空间中创建“每会话”互斥锁。跨度>
猜你喜欢
  • 2021-06-21
  • 2016-05-19
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多