Skip to content

Commit

Permalink
Added Mini Crash Dump Generation feature
Browse files Browse the repository at this point in the history
  • Loading branch information
hacksysteam committed Sep 11, 2015
1 parent f41ffa2 commit a3e92bb
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 3 deletions.
5 changes: 4 additions & 1 deletion node/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
# If you are runnning more than one node on the same system you will need to change this to avoid a conflict.
$server_port = 8080

# Set this false if you do not want to generate mini crash dumps
$save_minidump = true

################################################################################
# You probably dont need to edit these #
################################################################################
Expand Down Expand Up @@ -120,4 +123,4 @@
'testcase_head' => '',
# include the following inside the testcases <body>...</body>
'testcase_body' => ''
}
}
8 changes: 7 additions & 1 deletion node/core/debug/debugger.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ def initialize( crashes_dir, target_exe, reduction, target_url, logdir=nil )

return if not info

@@crash_info_for_minidump = info

if( info[:type] == 'breakpoint' )
@continuecode = ::Metasm::WinAPI::DBG_CONTINUE
return
Expand Down Expand Up @@ -657,6 +659,10 @@ def monitor
run_forever
rescue Grinder::Core::Debug::DebuggerException => e

if ( $save_minidump and not @reduction )
e.save_minidump(@os_process.handle, @os_thread.tid, @@crash_info_for_minidump[:st], @os_thread.context.c_struct)
end

# stop debugging this process!
::Metasm::WinAPI.debugactiveprocessstop( e.pid )

Expand Down Expand Up @@ -800,4 +806,4 @@ def self.main( klass, arguments )

end

end
end
119 changes: 118 additions & 1 deletion node/core/debug/debuggerexception.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
require 'core/logging'
require 'core/webstats'
require 'core/crypt'

require 'lib/metasm/metasm'

module Grinder

Expand Down Expand Up @@ -287,6 +287,123 @@ def save_log( src_file )

return text
end

def save_minidump( process_handle, threadid, exception_record, context_record )
generic_read = 0x80000000
generic_write = 0x40000000
create_always = 2
file_attribute_normal = 0x00000080

dbghelp_path = ".\\data\\#{ ::Metasm::WinAPI.host_cpu.size == 64 ? 'x64' : 'x86' }\\dbghelp.dll"

begin
::Metasm::WinAPI.new_api_c( 'typedef enum {
MiniDumpNormal = 0x00000000,
MiniDumpWithDataSegs = 0x00000001,
MiniDumpWithFullMemory = 0x00000002,
MiniDumpWithHandleData = 0x00000004,
MiniDumpFilterMemory = 0x00000008,
MiniDumpScanMemory = 0x00000010,
MiniDumpWithUnloadedModules = 0x00000020,
MiniDumpWithIndirectlyReferencedMemory = 0x00000040,
MiniDumpFilterModulePaths = 0x00000080,
MiniDumpWithProcessThreadData = 0x00000100,
MiniDumpWithPrivateReadWriteMemory = 0x00000200,
MiniDumpWithoutOptionalData = 0x00000400,
MiniDumpWithFullMemoryInfo = 0x00000800,
MiniDumpWithThreadInfo = 0x00001000,
MiniDumpWithCodeSegs = 0x00002000,
MiniDumpWithoutAuxiliaryState = 0x00004000,
MiniDumpWithFullAuxiliaryState = 0x00008000,
MiniDumpWithPrivateWriteCopyMemory = 0x00010000,
MiniDumpIgnoreInaccessibleMemory = 0x00020000,
MiniDumpWithTokenInformation = 0x00040000,
MiniDumpWithModuleHeaders = 0x00080000,
MiniDumpFilterTriage = 0x00100000,
MiniDumpValidTypeFlags = 0x001fffff
} MINIDUMP_TYPE;', dbghelp_path )

::Metasm::WinAPI.new_api_c( 'typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
DWORD ThreadId;
PEXCEPTION_POINTERS ExceptionPointers;
BOOL ClientPointers;
} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;', dbghelp_path )

::Metasm::WinAPI.new_api_c( 'WINUSERAPI BOOL WINAPI MiniDumpWriteDump(
__in HANDLE hProcess,
__in DWORD ProcessId,
__in HANDLE hFile,
__in MINIDUMP_TYPE DumpType,
__in PVOID ExceptionParam,
__in PVOID UserStreamParam,
__in PVOID CallbackParam
);', dbghelp_path )

::Metasm::WinAPI.new_api_c( 'WINBASEAPI HANDLE WINAPI CreateFileA(
__in LPCSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPVOID lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);', 'kernel32' )

crash_dump_dir = "#{ @dst_dir }#{ @dst_dir.end_with?('\\') ? '' : '\\' }#{@browser}\\"

if( not ::Dir.exists?( crash_dump_dir ) )
::Dir.mkdir( crash_dump_dir )
end

crash_dump_file = nil

0.upto( 0xFFFF ) do | count |
crash = "#{crash_dump_dir}#{@hash[0]}.#{@hash[1]}#{ count > 0 ? '.'+count.to_s : '' }.dmp"
if( not ::File.exists?( crash ) )
crash_dump_file = crash
break
end
end

raise 'Unable to create a unique crash dump file name' if not crash_dump_file

hdump_file = ::Metasm::WinAPI.createfilea( crash_dump_file,
generic_read | generic_write,
0,
nil,
create_always,
file_attribute_normal,
nil )

raise 'Unable to create crash dump file' if hdump_file == nil or hdump_file == ::Metasm::WinAPI::INVALID_HANDLE_VALUE

::Metasm::WinAPI.loadlibrarya( dbghelp_path )

exception_pointer = ::Metasm::WinAPI.alloc_c_struct( "EXCEPTION_POINTERS" )
exception_pointer[:exceptionrecord] = exception_record
exception_pointer[:contextrecord] = context_record

minidump_exception_info = ::Metasm::WinAPI.alloc_c_struct( "MINIDUMP_EXCEPTION_INFORMATION" )
minidump_exception_info[:threadid] = threadid
minidump_exception_info[:exceptionpointers] = exception_pointer
minidump_exception_info[:clientpointers] = nil

::Metasm::WinAPI.minidumpwritedump( process_handle,
@pid,
hdump_file,
::Metasm::WinAPI::MINIDUMPWITHFULLMEMORYINFO |
::Metasm::WinAPI::MINIDUMPWITHPRIVATEREADWRITEMEMORY |
::Metasm::WinAPI::MINIDUMPWITHPRIVATEWRITECOPYMEMORY |
::Metasm::WinAPI::MINIDUMPWITHUNLOADEDMODULES,
minidump_exception_info,
nil,
nil )

rescue ::Exception => e
print_error( "Error, unable to save the crash dump file (#{e.message})" )
end
end

end

end
Expand Down

0 comments on commit a3e92bb

Please sign in to comment.