4

Is it possible to release a resource (a file lock, timer) while a program is stopped in the debugger?

More generically, could I execute code before MSVC stops the program for debugging and after resuming execution?

I would like to accomplish to things: - Automatically release a file lock for editing during debugging. - Automatically reload the file after the process resumes - Prevent timers from triggering which overflow during the debug stop - Subtract the duration spent in debugging from timers

Workaround: If I cannot execute code before the program is stopped by the debugger, then detecting programmatically in the program that the debugger stopped the application would already help a lot.


Edit: I looked at Windows API functions for debugger integration, but it seems functions such as ContinueDebugEvent are only for the writer of a debugger and never for the process being debugged.


Edit 2: It seems that hotpatching the DbgBreakPoint function could be a way to intercept when the Debugger wants to break a process.

The main idea behind attaching is that a debugger calls the "DebugActiveProcess" function which ends up with calling the "RtlCreateUserThread" function to create a new remote thread into the target process, with the "DbgUiRemoteBreakin" function as the new thread entry point.

(from http://waleedassar.blogspot.de/2011/12/debuggers-anti-attaching-techniques.html)

DbgUiRemoteBreakin seems to call DbgBreakPoint to actually stop the process.


Edit 3: I hotpatched both DbgBreakPoint and DebugBreak to see if these methods get called from the MSVC debugger when I break interactively. Alas, they don't! It seems that the MSVC debugger just inserts int 3 at the break point locations and does not call any process method.


Edit 4: Reading up on Structured Exceptions and their interaction with the DebugBreak trap also results in a deadend: When hitting a break point, the interrupt 3 will first reach the kernel, which passes the Structured Exception to the debugger first (if attached). The debugger handles the interrupt and the application never sees it.

Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85
  • Do you think break-point condition will be useful. https://msdn.microsoft.com/library/7sye83ce(v=vs.100).aspx – vcp Mar 04 '16 at 08:10
  • Not really. Break-Point conditions are not visible inside the process being debugged. – Christopher Oezbek Mar 04 '16 at 09:57
  • http://stackoverflow.com/questions/3011703/advanced-visual-studio-kung-fu-test-calling-functions-from-the-immediate-wind – Hans Passant Mar 05 '16 at 13:17
  • @HansPassant: Using the intermediate window is kind of a manual process for each user. I would rather write code for putting the behavior directly into the application. – Christopher Oezbek Mar 05 '16 at 14:07
  • If you don't know how it works then anything looks possible I guess. C++ requires a compiler and a linker, those are not built into a debugger. You have to write that code *before* you debug. Just make sure you can easily call it from the Immediate Window. You are also ignoring good advice, using IsDebuggerPresent() in your code is a good idea. Simply use very long timeouts and don't lock a file when it returns TRUE. Writing debuggable code is as important as writing correct code. – Hans Passant Mar 05 '16 at 14:18
  • @HansPassant: I would like to make my code more debuggable to allow developers to break in situations that currently are ill-equipped to do so. Stopping our timers during debugging can be done in intermediate window, but it would be much greater in the program itself. The code is already written (before we debug), just how do we trigger it when the debugger is hit? – Christopher Oezbek Mar 05 '16 at 18:16
  • The debugger suspends the threads of the program; so don't think it's possible while suspended. – kvr Mar 09 '16 at 00:17
  • With SEH, if running the app without the debugger, the exception handler correctly suppresses the exception allowing you to do anything additional. If running under the debugger, the debugger will intercept the exception. – kvr Mar 09 '16 at 05:09

6 Answers6

1

DISCLAIMER: I myself use unit tests instead of such deep hacking with debugger, but never say never.

Is it possible to release a resource (a file lock) while a program is stopped in the debugger?

Debugger does not contain such features. Simplest is to use Process Explorer or other tools like that. However if you continue the program after then it does not have released resources anymore and subsequent attempts to access those will fail.

More generically, could I execute code before MSVC stops the program for debugging and after resuming execution?

You can temporarily edit your code to do whatever you want it to do before and after the spot where you plan to break it in debugger. Just don't forget to erase such temporary code later. You can also edit contents of data and even change execution order of code by forcefully setting the next statement to execute but that is tricky to do correctly.

My program locks a file, which I would like to exchange during debugging.

Also there is option not to lock the file while you debug by opening with OF_SHARE_DENY_NONE flag.

Öö Tiib
  • 10,809
  • 25
  • 44
0

This is not pretty but assuming you have no optimization flags set, add something like the following at relevant points.

bool executeMe = false;

if(executeMe) {
    // Code to release lock / close file ...
}

// ... normal code

Now just break prior to this and set the executeMe variable to true in the the debugger local variables view after evaluating the deceleration and prior to evaluating the if statement.

EDIT: Timer requirements .etc. could be similarly satisfied by recording the time prior to hitting the break point and using a statement such as above to adjust the timer back after exiting the debug block.

EDIT:

WRT automation, why not embed the condition for triggering your breakpoint within the program and do setup before calling __debugbreak()? The condition you use could be internal to your program or something like the existence of a trigger file such as below.

bool debugging = false;

struct stat unused;
if(!stat('.\\.debugflag',&unused)) {
    // Release locks, Close files, Stop timers .etc.
    // ...
    // Hook debuger. At this point you should be right to debug
    debugging = true;
    __debugbreak();  
}

// Code to debug ....

if(debugging) {
    // Cleanup after debug
}
Jarra McIntyre
  • 1,265
  • 8
  • 13
0

I can't comment yet, so apologies to other answers.

In MS Visual Studio you can detect if your application is running under a debugger using the API call

BOOL WINAPI IsDebuggerPresent(void);

From MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms680345%28v=vs.85%29.aspx

I can not see a way around writing your own locking per Jara's answer.

JimmyNJ
  • 1,134
  • 1
  • 8
  • 23
0

How about you write a function like this

void break( resource r1)
{
   release resource;
   throw false;
   rebind resource;
}

Instead of using a normal breakpoint you call the break function, which releases the resource, and throws a bool exception. Given that your programm doesn't handle bool exception, your MSVC Debugger will catch it and give you the option to break. You then can edit files/do everything and once your done you hit resume, resource will be rebound.

This obviously does not enable you to interactive set breakpoints at runtime, but maybe it helps

Daniel
  • 31
  • 2
0

How about using SetUnhandledExceptionFilter to install a global handler for your process where you check for interrupt 3 (debug breakpoint)?

The handler could release the locks and then continue with EXCEPTION_CONTINUE_SEARCH, essentially passing the breakpoint interrupt to the debugger?

You might be able to distinguish the breakpoint by looking at EXCEPTION_RECORD::ExceptionCode == EXCEPTION_BREAKPOINT

0

The only other solution I see, besides writing your own debugger or patching visual studio, is to scan all your code pages (marked with execute bit) for 0xCC byte (int 3 instruction) and patch them with a jump/call to your function that releases the resources then DebugBreakpoint().

In order to determine if the 0xCC is a int3 instruction or part of a longer opcode, you'd need to either disassemble the whole application/dll or take a copy of all code pages so that you can compare for 0xCC changes introduced by the debugger. You could perhaps use QueueUserAPC() to trigger the code page scan to occur as the debugger signals your thread to resume execution after placing a int3, giving you a chance to replace the int3 with a jump-to-my-function instruction before your app hits the int3.

Edit: you don't need to take copies of all code pages, just the addresses of all 0xCC bytes which appear in executable pages.