KNOWLEDGE BASE
Log In    |    Knowledge Base    |    4D Home
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.