Tech Tip: Utility Method to Enable Procdump
PRODUCT: 4D | VERSION: 20 | PLATFORM: Win
Published On: July 1, 2024
Procdump is a useful tool to assist in diagnosing crashes and hangs on Windows. The tool watches a process and when a crash or hang occurs it will create a dump file which is a memory dump of the process.
The latest version of the tool can be obtained from the following link by Microsoft:
https://learn.microsoft.com/en-us/sysinternals/downloads/procdump
The tool can be used from the command line as explained in the link above. As such, it is also possible to use the tool from 4D. The following method uses System workers to start up Procdump to watch the calling instance of 4D:
// ---------------------------------------------------- // Method: Util_RunProcDump // Description // This method will run Procdump in a System Worker Process // Procdump.zip should be placed at Resources directory // and/or // procdump64.exe should be placed at \Resources\Procdump\procdump64.exe // // WARNING // Procdump gets attached to a process, if it is closed // without disconnecting it will kill the attached process. // If a 4D process completes, any system workers created by the process is also closed. // This will cause 4D to close if this process is quit unexpectedly. // Procdump can be detached by calling procdump64.exe and passing -cancel [PID of attached process] // [path to procdump64.exe] -cancel [PID] // as done with the second system worker if this process needs to be closed. // // Parameters // - $dumpDestination_Path_t : (Optional) Path to directory to store dump if generated. // Defaults to Database's Logs folder // // // - $watchCrash_b : (Optional) Boolean, True, Default, to watch a crash // or False to not watch a Crash // // - $watchHang_b : (Optional) Boolean, True to watch a Hang // or False, Default, to not watch a Hang // // At least one or both of the watchers should be enabled. // // // - $hideConsole_b : (Optional) Boolean, True, Default, to hide Console Window // or False to not hide Console Window // If console window is not hidden it will not display any feedback text. // However, Ctrl+C can be used on it to detach Procdump from 4D // // ---------------------------------------------------- #DECLARE(\ $dumpDestination_Path_t : Text; \ $watchCrash_b : Boolean; \ $watchHang_b : Boolean; \ $hideConsole_b : Boolean) var $resources_Path_t : Text var $procDump_Path_t : Text var $procDumpZip_Path_t : Text var $procDumpZip_4dFile : 4D.File var $archive_4dZip : 4D.ZipArchive var $watchers_t : Text var $pid_t : Text var $cmd_t : Text var $optionsObj : Object var $procDumpAttach_Worker : 4D.SystemWorker var $procDumpDetach_Worker : 4D.SystemWorker var exitFlag_b : Boolean exitFlag_b:=False If (Count parameters<2) $watchCrash_b:=True End if If (($watchCrash_b=True) | ($watchHang_b=True)) $resources_Path_t:=Get 4D folder(Current resources folder) $procDump_Path_t:=$resources_Path_t+"Procdump"+Folder separator+"procdump64.exe" $procDumpZip_path:=$resources_Path_t+"Procdump.zip" If (Test path name($procDumpZip_Path_t)=Is a document) $procDumpZip_4dFile:=File($procDumpZip_Path_t; fk platform path) $procDumpZip_4dZip:=ZIP Read archive($procDumpZip_4dFile) $procDumpZip_4dZip.root.copyTo(Folder($resources_Path_t; fk platform path); fk overwrite) End if If ((Test path name($procDump_Path_t)=Is a document)) If ($dumpDestination_Path_t="") $dumpDestination_Path_t:=Get 4D folder(Logs folder)+"Dumps"+Folder separator Else If (Not(Test path name($dumpDestination_Path_t)=Is a folder)) CREATE FOLDER($dumpDestination_Path_t; *) End if End if $watchers_t:="" If ($watchCrash_b) $watchers_t:=" -e" End if If ($watchHang_b) $watchers_t:=$watchers_t+" -h" End if $pid_t:=String(Get application info.pid) $cmd_t:="\""+$procDump_Path_t+"\" /accepteula"+$watchers_t+" -ma "+$pid_t+" \""+$dumpDestination_Path_t+"\"" If (($hideConsole_b=True) | (Count parameters<4)) $optionsObj:=New object("hideWindow"; True) Else $optionsObj:=New object("hideWindow"; False) End if $procDumpAttach_Worker:=4D.SystemWorker.new($cmd_t; $optionsObj) $procDumpAttach_Worker.wait(1) While ((exitFlag_b=False) & ($procDumpAttach_Worker.terminated=False)) DELAY PROCESS(Current process; 30) $procDumpAttach_Worker.wait(1) End while $procDumpAttach_Worker.wait(1) If ($procDumpAttach_Worker.terminated=False) $procDumpDetach_Worker:=4D.SystemWorker.new("\""+$procDump_Path_t+"\" -cancel "+$pid_t) $procDumpDetach_Worker.wait(1) End if End if End if |
The method's description explains most of the method. The method should be called as a stored procedure as the system worker will close automatically when the process does. The process is also used to gracefully detach Procdump. When Procdump is attached to a process, if the instance of Procdump is not closed gracefully it will also close the attached process.
This method can be applied to a database and then using some way to toggle it, it is possible to easily enable procdump if needed without needing the users to do anything besides enable it in some way.