问题
Here's my scenario: I have a program which produces debug output with OutputDebugString()
which maybe contains messages indicating bugs. I want to run this program inside daily build and automatically listen to debug output, parse it and report suspicious output.
There're several examples of such listener implementations, for example this one. They all do the same - listen to a system-wide event and then read data from a file mapping. The problem is this protocol allows for only one instance of the listener - whoever grabs the event first is the only one to access the output.
Same with DebugView program. If I have an instance running then starting another instance yields a "disconnected" instance and it will fail to "connect local".
The daily build runs multiple programs simultaneously and so I want to be able to run several instances of this listener and have each only listen to a specific program. Looks live Visual Studio can do that - when I start a program under Visual Studio I only see the debug output from that very program, not from others and I can also run several instances of Visual Studio and debug a program it each of them at the same time
Is it possible to run several instances of program equivalent to DebugView such that each instances only listens to a specific program being observed and instances don't interfere with each other?
回答1:
I followed the hint given by user 500 - Internal Server Error in the comments and tried the "pretend Visual Studio" way. It's very close to "hold my beer" difficulty level (but I have 10+ years of WinAPI software development experience). The whole thing took several hours and the implementation is less than 200 lines of C++ code including some bulky code for calling WinAPI functions and the code which filters the output and reports suspicious items in a usable way.
The fun part is that I used Visual Studio to write and debug the code - Visual Studio was acting as debugger for my program being developed and the program being developed was acting as debugger to the program which was producing curious debug output and this chain works just fine.
Here's a good tutorial to get the idea and some inspiration: Writing a basic Windows debugger This is an MSDN explanation of how to write a debugger main loop: Writing the Debugger's Main Loop.
This is how it works:
- Start the program you want to process debug output from using
CreateProcess()
and passingDEBUG_ONLY_THIS_PROCESS
flag. This starts the program suspended and in "being debugged" mode. - Run an infinite loop and call
WaitForDebugEvent()
on each iteration. CallingWaitForDebugEvent()
resumes the suspended program and allows it to run until the next debug event happens. - Process
OUTPUT_DEBUG_STRING_EVENT
, useReadProcessMemory()
to copy the string from the process being debugged, process the string as you see fit. - Also process
EXIT_PROCESS_DEBUG_EVENT
- it means the process being debugged exited and you likely want to end the loop. - Also process
EXCEPTION_DEBUG_EVENT
- whenEXCEPTION_DEBUG_INFO.dwFirstChance
is zero you have to terminate the process being debugged usingTerminateProcess()
otherwise you'll get an inconvenient "the program has stopped working" dialog from Windows - Call
ContinueDebugEvent()
at the end of loop iteration, passDBG_EXCEPTION_NOT_HANDLED
.
That's all. Yes, now you can claim you have experience writing a debugger.
来源:https://stackoverflow.com/questions/58374587/how-would-my-program-listen-to-outputdebugstring-output-and-allow-launch-of-mult