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

Debugged applications may crash randomly after calling Debug.stop() #23

Open
chschmitt opened this issue Jun 22, 2017 · 3 comments
Open
Labels

Comments

@chschmitt
Copy link

The title pretty much describes the problem. I am debugging various 32 bit applications using the Debug class. Before calling Debug.next() I check a threading.Event in my debugging loop to see if the debugger should detach. If the event is set, Debug.stop() is called. The debugger quits nicely, but often the debugged application crashes (showing the windows dialog "<foo.exe> has stopped working").
The exception codes I saw were either 0x80000003 or 0x80000004.
Is that a general issue when debugging windows applications or is it possibly a bug?

@MarioVilas
Copy link
Owner

Sounds like a bug indeed. 0x80000003 is EXCEPTION_BREAKPOINT, the exception raised when a breakpoint instruction is executed. This would mean WinAppDbg is not correctly removing all breakpoints before detaching.

Question, are you trying to call Debug.stop() in response to a breakpoint event?

As a workaround, I suppose you could remove all breakpoints in your script before calling stop(), but I get the feeling the problem is not quite there, but more on the lines of the breakpoint event not being ignored when continuing execution...

@chschmitt
Copy link
Author

The event is set from another thread. Effectively, stop() is called immediately before my version of next() in the debugger's main loop, not from an event handler, i.e. dispatch() has already returned. I found that get_debugee_count() is still 1 when stop() returns.

def next(self):
    # exceptions are caught in main loop
    self.debug.wait()
    try:
        self.debug.dispatch()
    finally:
        self.debug.cont()

@chschmitt
Copy link
Author

chschmitt commented Jun 22, 2017

I tried some things and I suspect that the removal of a breakpoint while it is hit leaves the debugged process messed up (i.e. with the break instruction still in memory). The following seems to work:

  1. Disable all breakpoints when stop event is set
  2. Continue main loop
  3. Break main loop and call stop() when a timeout was hit
    def mainloop(self):
        while True:
            if self.shared.stop_event.is_set():
                self.debug.disable_all_breakpoints()
            try:
                if not self.next() and self.shared.stop_event.is_set():
                    print('stop is set & got wait timeout: breaking main loop')
                    break
            except Exception:
                print('error in tracer loop, calling stop_debug() unconditionally')
                self.debug.stop()
                raise
            if not self.debug:
                print('all debugees gone')
                break
        self.debug.stop()
        print('debug event loop has been left normally')
    
    def next(self):
        try:
            self.debug.wait(5000)
        except WindowsError as e:
            if e.winerror == 121:
                return False
            raise
        try:
            self.debug.dispatch()
        finally:
            self.debug.cont()
        return True

BTW: Thanks for your excellent library

@MarioVilas MarioVilas added the bug label Apr 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants