Debugging Engines
This section covers the basics on how to attach a debugger to an Engine.
Java
The Java Platform Debugger Architecture (JPDA) enables the connection of a debugger to the Engine via a socket. You can set the socket used for debugging in the Engine Configuration. Create a new Engine Configuration or modify an existing one, and change the value of Debug Start Port. If you have a single Engine per Engine Daemon, set this value to the port you wish to use on each Engine. If you have more than one Engine per Engine Daemon, the value given in Debug Start Port is the port used for the first Engine instance, and the port is incremented for each additional Engine Instance. You can also set Debug Suspend to true, which keeps the Engine suspended until a debugger is attached.
.NET, Windows DLL
Microsoft Visual Studio comes with a remote debugging facility. To debug, you must first make sure that you build with debug symbols, and deploy the symbols (PDB) file with the DLL. Once the Engine has logged in, you attach the debugger to the invoke.exe process via the Processes dialog on the Debug menu.
CPPDriver and Linux
GDB can be used to debug native code in CPPDriver or JNI in Linux. Also, GDB can be useful in identifying unusual problems with the Linux JVM. However, there are some subtle issues when trying to use GDB on a JVM, as is the case with the GridServer Engine.
When attaching GDB to the Engine, you must specify the LD_LIBRARY_PATH to both the Engine components and the JVM components.
LD_LIBRARY_PATH=lib:jre/lib/i386:jre/lib/i386/native_threads:jre/lib/i386/server:resources/lib/linux
You must also obtain the process ID of a running invoke (or invokeGCC34) process from the ps command. It's also easier if you run GDB from the base directory of the Engine install (typically DSEngine). The GDB command used is similar to this:
gdb bin/invoke $INVOKEPID
Replace bin/invoke with bin/invokeGCC34 when using GCC34.
One difficulty with debugging C++ code is that your application shared objects are loaded only when the Service is instantiated, so it becomes difficult to set a breakpoint in the application shared object. (However, more recent versions of GDB feature deferred symbol resolution, which makes this possible.) A technique that works in this instance is to have your application Service method include some conditional code to enter a loop checking some variable value that is never changed by the application code, effectively creating an infinite loop. When you need to attach GDB, trigger the conditional that causes the loop to be entered on the next invocation. Then attach GDB as above. You’ll see that the invoke process is stopped while running in the loop. At that point, you can change the loop evaluation value so that the infinite loop is exited, and the code continues to your breakpoint where you can continue debugging.