Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Isn't there a possible deadlock issue with DetourUpdateThread and DetourTransactionCommit? #70

Open
AlphaModder opened this issue Jul 11, 2019 · 11 comments
Labels
bug Something isn't working

Comments

@AlphaModder
Copy link

I notice that both DetourUpdateThread and DetourTransactionCommit use new and delete in their code. Assuming these eventually translate to calls to GlobalAlloc and GlobalFree, isn't it possible for deadlock to occur if a thread previously suspended by DetourUpdateThread currently holds a lock on the default heap? This could be avoided by having Detours allocate its own heap with CreateHeap and using that heap for all allocations that occur during a transaction.

@sonyps5201314
Copy link
Contributor

Yes, it's possible. I met it.

@fredemmott
Copy link

fredemmott commented Jan 16, 2022

I'm fairly reliably hitting this, and @adams85's patch mentioned above fixes it for me (apply with --ignore-whitespace to get a readable diff) - however, in debug builds, there's another deadlock in debug builds, as DETOUR_TRACE calls printf

@sonyps5201314
Copy link
Contributor

sonyps5201314 commented Jan 16, 2022

please use PR #144 to fix your rest problems like DETOUR_TRACE you said.

I'm fairly reliably hitting this, and @adams85's patch mentioned above fixes it for me (apply with --ignore-whitespace to get a readable diff) - however, in debug builds, there's another deadlock in debug builds, as DETOUR_TRACE calls printf

@fredemmott
Copy link

fredemmott commented Jan 16, 2022

While that might be a more thorough fix, I'm not comfortable diverging that far from master, or familiar enough with Detours to review #144 even for my own use. The smaller patch - and sticking to release builds of Detours - is a better solution for me.

@fredemmott
Copy link

@sonyps5201314 fwiw, while I don't work on Detours or at Microsoft, it's generally best to create pull requests that address a single bug/issue at a time, keeping them as small as possible - this makes them much easier to review, and usually leads to them getting merged by the project maintainers much faster.

@fredemmott
Copy link

fredemmott commented Jan 16, 2022

Patch-free workaround:

  • call HeapLock(GetProcessHeap()) before DetourTransactionBegin()
  • call HeapFree(GetProcessHeap()) after DetourTransactionCommit()/DetourTransactionAbort()

Edit: turns out this is suggested at https://devblogs.microsoft.com/oldnewthing/20170125-00/?p=95255

@sonyps5201314
Copy link
Contributor

@fredemmott,Please read the latest reply in PR #144 to answer your doubts.

adams85 added a commit to adams85/Detours that referenced this issue Apr 10, 2022
@adams85
Copy link

adams85 commented Apr 10, 2022

@fredemmott Thanks for pointing out HeapLock/HeapUnlock. This is much simpler, so I've updated my fork to use this. I'll even submit this as a PR, let's see how the maintainers like it.

@adams85
Copy link

adams85 commented Apr 12, 2022

As it turned out, the HeapLock approach isn't viable because of a nasty race condition (for more details, see #232 (comment) and #144 (comment)). It seems that the only fail-safe way to tackle this bug is HeapCreate and custom allocation as mentioned above.

@fredemmott
Copy link

fredemmott commented Apr 12, 2022

To be clear, I'm only suggesting it as a work around for common cases. The thorough new allocator approach is more thorough, and likely better for merging.

Yep, if another thread has the lock and is busy or suspended, it can't acquire the lock until that's free. Whether this is OK for a workaround depends on your use case.

HeapLock/HeapUnlock should always be in matched pairs, so being unlocked by another thread "shouldn't" happen. This would be extremely misbehaved code, but there's admittedly lots of misbehaved code out there - and I'm surprised that HeapUnlock doesn't require that HeapUnlock is called from the same thread as HeapLock.

I'd much rather see a thorough fix like the custom heap/alloc merged into detours - but until that's done, where I am able to assume there's no long-running heap locks and no cross-thread heap unlock, I prefer to minimize the amount of code that I'm using that hasn't been reviewed/merged by the project maintainers.

@PDeets
Copy link
Member

PDeets commented Oct 21, 2022

I started a PR which enables you to use Detours in a way that avoids deadlocks. See the PR description for details at #261. This doesn't solve the issue for any existing Detours user. You have to change your code that uses Detours in the way explained in the PR description.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants