I ended up writing a Netbeans module that interacts with supporting code in my application to catch child process creation and then automatically attaches to them on a debug port they're using.
It does this through an automatically created hidden breakpoint (on a method my application calls when a child is spawned). That breakpoint evaluates a static method in the support class in my application to get the debug port. It then tries to attach to that port and resumes the application from the breakpoint.
The end effect is that I get automatic attachment to a child process with no user intervention. Just Start-Debug on the main application and then breakpoints get hit seamlessly in the child processes. Like the gdb option (set follow-fork-mode child) to attach and follow children processes after a fork/exec.
It only works in my specific case as I control both the Netbeans plugin module and the application under development.
I can't post the whole source here, but the things I used to achieve this included:
DebuggerManager.getDebuggerManager().addDebuggerListener();
MethodBreakpoint.create();
RequestProcessor.getDefault().post();
DebuggerInfo.create ("netbeans-jpda-AttachingDICookie", new Object [] {AttachingDICookie.create ("localhost",port)} );
DebuggerManager.getDebuggerManager().startDebugging()
JPDADebugger d = DebuggerEngine.lookupFirst("", JPDADebugger.class);
JPDADebugger.waitRunning();
The magic string "netbeans-jpda-AttachingDICookie" was the hardest thing to figure out in this. It took debugging the netbeans debugger through a normal attach process call to find this value. I have not been able to find it documented anywhere.