Tuesday, 17 October 2017

Remote debugger recalcitrance

My development machine in my main week day job does not have some custom hardware that a nearby test machine does. It doesn’t make sense to load up the development environment onto the test machine for various reasons, so I am a fairly irregular user of remote debugging against my Win32 application.

As it happens the client language is C++Builder (classic compiler), but I expect this issue to apply equally to Delphi (I’d be interested to know from anyone who can confirm one way or another).

Remote debugging works quite nicely via PAServer. It is certainly straightforward in comparison to the games we had to play some years back – PAServer seems to have simplified the setup quite nicely.

Granted, stepping is pretty slow, but then there’s quite a lot going on and a certain amount of information for PAServer retrieve from the remote debugger (rmtdbg250.exe) and then to send back to PAClient and to the IDE, so I can take that.

What gets my goat, though, is what happens when the program ends. Often I have to kill the application (Ctrl+F2, or Run, Program Reset), but often the application exits quite naturally.

More often than not I can’t make a change in the code and have F9 successfully compile and run up the app remotely again. I get this:

[PAClient Error] Error: E0009 Cannot create file "\\?\C:\Program Files (x86)\Embarcadero\PAServer\19.0\scratch-dir\some_subfolder\project_name\project_name.tds". The process cannot access the file because it is being used by another process

As it turns out this is indeed true. There are two copies of the remote debugger, rmtdbg250.exe (in the case of RAD Studio 10.2.x) running, at least one of which has a handle open on the TDS symbol file.

This is quite annoying, as I have to use Task Manager to show me the two remote debuggers and manually kill them. In the grand scale of things, there are worse things, of course. But over a number of deploy/debug cycles this does get annoying.

Maybe I need to revert to directly running the Remote Debug Server?

Anyway, in lieu of a good reason for this and in the absence of good behaviour from the remote debuggers I’ve had to expedite the clean-up process by way of another command script (aka batch file). This gets the process IDs (PIDs) of the remote debuggers and has Windows kill them. It has to do this twice though, as the first time round one of the pesky debugger instances always survives the cull.

Anyway, on the off-chance it is of any use to others, here is the script, which I call KillDebuggers.bat. Apologies for its slightly prolix nature – I like to keep alternative approaches around just to remind myself of how I can do things.

@echo off

rem When remote debugging, this batch file is useful to kill the
rem remote debugger instances that refuse to die naturally


rem First round

echo.&echo First round of Wipe Out The Debuggers&echo.

call :sic_em_boy

rem Second round

echo.&echo Second round of Wipe Out The Debuggers&echo.

call :sic_em_boy


goto :EOF


set CMDLINE=tasklist /FO TABLE /NH /FI "IMAGENAME eq rmtdbg250.exe"
rem This gives output lines like:

rem rmtdbg250.exe 776 Console 2 6,456 K

rem The PID is token 2, if we consider this as white space delimited
rem However if no debuggers are running we get:

rem INFO: No tasks are running which match the specified criteria.

rem In that message token 2 is "No"

for /f "tokens=2 delims= " %%A in ('%CMDLINE%') do (
  if %%A == No (
    echo No debugger found!
  ) else (
    taskkill /PID %%A

rem Or we could simply say:

rem taskkill /IM rmtdbg250.exe

exit /B

If anyone has any input on this issue, please get in touch via the comments.