Add Windows support to test tool
This commit is contained in:
parent
08c991129d
commit
51ab414c1c
@ -9,6 +9,7 @@ install:
|
|||||||
- cd ambuild
|
- cd ambuild
|
||||||
- C:\python27\python.exe setup.py install
|
- C:\python27\python.exe setup.py install
|
||||||
- cd %APPVEYOR_BUILD_FOLDER%
|
- cd %APPVEYOR_BUILD_FOLDER%
|
||||||
|
- '"%VS140COMNTOOLS%\vsvars32.bat"'
|
||||||
- breakpad.bat
|
- breakpad.bat
|
||||||
build_script:
|
build_script:
|
||||||
- '"%VS140COMNTOOLS%\vsvars32.bat"'
|
- '"%VS140COMNTOOLS%\vsvars32.bat"'
|
||||||
@ -18,3 +19,5 @@ build_script:
|
|||||||
- C:\python27\python.exe build.py
|
- C:\python27\python.exe build.py
|
||||||
on_success:
|
on_success:
|
||||||
- C:\python27\python.exe ..\upload.py
|
- C:\python27\python.exe ..\upload.py
|
||||||
|
#on_finish:
|
||||||
|
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||||
|
20
breakpad.bat
20
breakpad.bat
@ -1,3 +1,5 @@
|
|||||||
|
@echo on
|
||||||
|
|
||||||
IF EXIST breakpad\NUL GOTO HASBREAKPAD
|
IF EXIST breakpad\NUL GOTO HASBREAKPAD
|
||||||
mkdir breakpad
|
mkdir breakpad
|
||||||
:HASBREAKPAD
|
:HASBREAKPAD
|
||||||
@ -18,15 +20,15 @@ IF EXIST gyp\NUL GOTO HASGYP
|
|||||||
git clone --depth=1 --branch=master https://chromium.googlesource.com/external/gyp.git gyp
|
git clone --depth=1 --branch=master https://chromium.googlesource.com/external/gyp.git gyp
|
||||||
:HASGYP
|
:HASGYP
|
||||||
|
|
||||||
IF EXIST build\NUL GOTO HASBUILD
|
powershell -Command "& {(Get-Content src\src\build\common.gypi).replace('''WarnAsError'': ''true'',', '''WarnAsError'': ''false'',') | Set-Content src\src\build\common.gypi}"
|
||||||
mkdir build
|
|
||||||
:HASBUILD
|
|
||||||
cd build
|
|
||||||
|
|
||||||
..\gyp\gyp.bat --no-circular-check ..\src\src\client\windows\handler\exception_handler.gyp
|
cmd /c gyp\gyp.bat --no-circular-check src\src\client\windows\handler\exception_handler.gyp
|
||||||
msbuild ..\src\src\client\windows\handler\exception_handler.sln /m /p:Configuration=Release
|
msbuild src\src\client\windows\handler\exception_handler.sln /m /p:Configuration=Release
|
||||||
|
|
||||||
..\gyp\gyp.bat --no-circular-check ..\src\src\client\windows\crash_generation\crash_generation.gyp
|
cmd /c gyp\gyp.bat --no-circular-check src\src\client\windows\crash_generation\crash_generation.gyp
|
||||||
msbuild ..\src\src\client\windows\crash_generation\crash_generation.sln /m /p:Configuration=Release
|
msbuild src\src\client\windows\crash_generation\crash_generation.sln /m /p:Configuration=Release
|
||||||
|
|
||||||
cd ..\..
|
cmd /c gyp\gyp.bat --no-circular-check src\src\processor\processor.gyp
|
||||||
|
msbuild src\src\processor\processor.sln /m /p:Configuration=Release
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
@ -116,9 +116,6 @@ def AddHL2Library(name, dest):
|
|||||||
debug_info = []
|
debug_info = []
|
||||||
|
|
||||||
AddNormalLibrary('accelerator.ext', 'extensions')
|
AddNormalLibrary('accelerator.ext', 'extensions')
|
||||||
|
|
||||||
|
|
||||||
if AMBuild.target['platform'] == 'linux':
|
|
||||||
AddExecutable('test-crash-dump-generation', 'configs')
|
AddExecutable('test-crash-dump-generation', 'configs')
|
||||||
|
|
||||||
job.AddCommandGroup(bincopies)
|
job.AddCommandGroup(bincopies)
|
||||||
|
@ -6,7 +6,7 @@ from ambuild.command import ShellCommand
|
|||||||
from ambuild.command import DirectCommand
|
from ambuild.command import DirectCommand
|
||||||
|
|
||||||
def BuildEverything():
|
def BuildEverything():
|
||||||
if AMBuild.target['platform'] not in ['linux']:
|
if AMBuild.target['platform'] not in ['linux', 'windows']:
|
||||||
return
|
return
|
||||||
|
|
||||||
compiler = SM.DefaultCompiler()
|
compiler = SM.DefaultCompiler()
|
||||||
@ -16,6 +16,9 @@ def BuildEverything():
|
|||||||
if AMBuild.target['platform'] in ['linux']:
|
if AMBuild.target['platform'] in ['linux']:
|
||||||
compiler['POSTLINKFLAGS'].append('-lstdc++')
|
compiler['POSTLINKFLAGS'].append('-lstdc++')
|
||||||
compiler['POSTLINKFLAGS'].append('-pthread')
|
compiler['POSTLINKFLAGS'].append('-pthread')
|
||||||
|
elif compiler.cc.name == 'msvc':
|
||||||
|
compiler['POSTLINKFLAGS'].remove('/SUBSYSTEM:WINDOWS')
|
||||||
|
compiler['POSTLINKFLAGS'].append('/SUBSYSTEM:CONSOLE')
|
||||||
|
|
||||||
name = 'test-crash-dump-generation'
|
name = 'test-crash-dump-generation'
|
||||||
extension = AMBuild.AddJob(name)
|
extension = AMBuild.AddJob(name)
|
||||||
@ -42,14 +45,15 @@ def BuildEverything():
|
|||||||
binary.AddObjectFiles([lib])
|
binary.AddObjectFiles([lib])
|
||||||
|
|
||||||
elif AMBuild.target['platform'] in ['windows']:
|
elif AMBuild.target['platform'] in ['windows']:
|
||||||
libs = ['exception_handler', 'common']
|
libs = [
|
||||||
for lib in libs:
|
os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'client', 'windows', 'handler', 'Release', 'lib', 'common.lib'),
|
||||||
path = os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'client', 'windows', 'handler', 'Release', 'lib', lib + '.lib')
|
os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'client', 'windows', 'handler', 'Release', 'lib', 'exception_handler.lib'),
|
||||||
if os.path.isfile(path):
|
os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'client', 'windows', 'crash_generation', 'Release', 'lib', 'crash_generation_client.lib'),
|
||||||
binary.RelinkIfNewer(path)
|
os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'processor', 'Release', 'lib', 'libdisasm.lib'),
|
||||||
binary['POSTLINKFLAGS'].extend([path])
|
os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'processor', 'Release', 'lib', 'processor.lib'),
|
||||||
|
]
|
||||||
|
|
||||||
path = os.path.join(AMBuild.sourceFolder, 'breakpad', 'src', 'src', 'client', 'windows', 'crash_generation', 'Release', 'lib', 'crash_generation_client.lib')
|
for path in libs:
|
||||||
if os.path.isfile(path):
|
if os.path.isfile(path):
|
||||||
binary.RelinkIfNewer(path)
|
binary.RelinkIfNewer(path)
|
||||||
binary['POSTLINKFLAGS'].extend([path])
|
binary['POSTLINKFLAGS'].extend([path])
|
||||||
|
@ -1,7 +1,30 @@
|
|||||||
|
#if defined _LINUX
|
||||||
#include "client/linux/handler/exception_handler.h"
|
#include "client/linux/handler/exception_handler.h"
|
||||||
#include "common/linux/linux_libc_support.h"
|
#include "common/linux/linux_libc_support.h"
|
||||||
#include "third_party/lss/linux_syscall_support.h"
|
#include "third_party/lss/linux_syscall_support.h"
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define my_jmp_buf sigjmp_buf
|
||||||
|
#define my_setjmp(x) sigsetjmp(x, 0)
|
||||||
|
#define my_longjmp siglongjmp
|
||||||
|
|
||||||
|
using google_breakpad::MinidumpDescriptor;
|
||||||
|
|
||||||
|
#elif defined _WINDOWS
|
||||||
|
#define _STDINT // ~.~
|
||||||
|
#include "client/windows/handler/exception_handler.h"
|
||||||
|
|
||||||
|
#define my_jmp_buf jmp_buf
|
||||||
|
#define my_setjmp(x) setjmp(x)
|
||||||
|
#define my_longjmp longjmp
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error Bad platform.
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <google_breakpad/processor/minidump.h>
|
#include <google_breakpad/processor/minidump.h>
|
||||||
#include <google_breakpad/processor/minidump_processor.h>
|
#include <google_breakpad/processor/minidump_processor.h>
|
||||||
#include <google_breakpad/processor/process_state.h>
|
#include <google_breakpad/processor/process_state.h>
|
||||||
@ -9,14 +32,10 @@
|
|||||||
#include <google_breakpad/processor/stack_frame.h>
|
#include <google_breakpad/processor/stack_frame.h>
|
||||||
#include <processor/pathname_stripper.h>
|
#include <processor/pathname_stripper.h>
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
|
||||||
using google_breakpad::MinidumpDescriptor;
|
#include <setjmp.h>
|
||||||
|
|
||||||
using google_breakpad::ExceptionHandler;
|
using google_breakpad::ExceptionHandler;
|
||||||
|
|
||||||
using google_breakpad::Minidump;
|
using google_breakpad::Minidump;
|
||||||
@ -28,9 +47,10 @@ using google_breakpad::StackFrame;
|
|||||||
using google_breakpad::PathnameStripper;
|
using google_breakpad::PathnameStripper;
|
||||||
using google_breakpad::CodeModule;
|
using google_breakpad::CodeModule;
|
||||||
|
|
||||||
sigjmp_buf envbuf;
|
my_jmp_buf envbuf;
|
||||||
char path[1024];
|
char path[1024];
|
||||||
|
|
||||||
|
#if defined _LINUX
|
||||||
static bool dumpCallback(const MinidumpDescriptor &descriptor, void *context, bool succeeded)
|
static bool dumpCallback(const MinidumpDescriptor &descriptor, void *context, bool succeeded)
|
||||||
{
|
{
|
||||||
if (succeeded) {
|
if (succeeded) {
|
||||||
@ -43,10 +63,28 @@ static bool dumpCallback(const MinidumpDescriptor &descriptor, void *context, bo
|
|||||||
sys_write(STDOUT_FILENO, "\n", 1);
|
sys_write(STDOUT_FILENO, "\n", 1);
|
||||||
|
|
||||||
my_strlcpy(path, descriptor.path(), sizeof(path));
|
my_strlcpy(path, descriptor.path(), sizeof(path));
|
||||||
siglongjmp(envbuf, 1);
|
my_longjmp(envbuf, 1);
|
||||||
|
|
||||||
return succeeded;
|
return succeeded;
|
||||||
}
|
}
|
||||||
|
#elif defined _WINDOWS
|
||||||
|
static bool dumpCallback(const wchar_t *dump_path, const wchar_t *minidump_id, void *context, EXCEPTION_POINTERS *exinfo, MDRawAssertionInfo *assertion, bool succeeded)
|
||||||
|
{
|
||||||
|
if (succeeded) {
|
||||||
|
printf("Wrote minidump to: %ls\\%ls.dmp\n", dump_path, minidump_id);
|
||||||
|
} else {
|
||||||
|
printf("Failed to write minidump to: %ls\\%ls.dmp\n", dump_path, minidump_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: setjmp/longjmp doesn't play nicely with SEH on Windows, so we never get back.
|
||||||
|
// But the exception handler is called and writes the dump, so the user can just invoke us again.
|
||||||
|
|
||||||
|
// snprintf(path, sizeof(path), "%ls\\%ls.dmp", dump_path, minidump_id);
|
||||||
|
// my_longjmp(envbuf, 1);
|
||||||
|
|
||||||
|
return succeeded;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -54,12 +92,16 @@ int main(int argc, char *argv[])
|
|||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
generateCrash = true;
|
generateCrash = true;
|
||||||
|
|
||||||
if (sigsetjmp(envbuf, 0) == 0) {
|
if (my_setjmp(envbuf) == 0) {
|
||||||
|
#if defined _LINUX
|
||||||
MinidumpDescriptor descriptor(".");
|
MinidumpDescriptor descriptor(".");
|
||||||
ExceptionHandler *handler = new ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1);
|
ExceptionHandler *handler = new ExceptionHandler(descriptor, NULL, dumpCallback, NULL, true, -1);
|
||||||
|
#elif defined _WINDOWS
|
||||||
|
ExceptionHandler *handler = new ExceptionHandler(L".", NULL, dumpCallback, NULL, ExceptionHandler::HANDLER_ALL);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Test shit here.
|
volatile int *ptr = (volatile int *)(0xdeadbeef);
|
||||||
__builtin_trap();
|
*ptr = 0;
|
||||||
|
|
||||||
delete handler;
|
delete handler;
|
||||||
return 0;
|
return 0;
|
||||||
@ -70,19 +112,9 @@ int main(int argc, char *argv[])
|
|||||||
argc = 2;
|
argc = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ONELINE
|
|
||||||
|
|
||||||
#ifdef ONELINE
|
|
||||||
# define CRPRE "|"
|
|
||||||
# define CRPOST ""
|
|
||||||
#else
|
|
||||||
# define CRPRE ""
|
|
||||||
# define CRPOST "\n"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if (!generateCrash) {
|
if (!generateCrash) {
|
||||||
my_strlcpy(path, argv[i], sizeof(path));
|
strncpy(path, argv[i], sizeof(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
MinidumpProcessor minidumpProcessor(nullptr, nullptr);
|
MinidumpProcessor minidumpProcessor(nullptr, nullptr);
|
||||||
@ -115,7 +147,7 @@ int main(int argc, char *argv[])
|
|||||||
frameCount = 10;
|
frameCount = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("1|%d|%s|%x|%d" CRPOST, processState.crashed(), processState.crash_reason().c_str(), (intptr_t)processState.crash_address(), requestingThread);
|
printf("1|%d|%s|%x|%d", processState.crashed(), processState.crash_reason().c_str(), (intptr_t)processState.crash_address(), requestingThread);
|
||||||
|
|
||||||
std::map<const CodeModule *, unsigned int> moduleMap;
|
std::map<const CodeModule *, unsigned int> moduleMap;
|
||||||
|
|
||||||
@ -126,7 +158,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
auto debugFile = PathnameStripper::File(module->debug_file());
|
auto debugFile = PathnameStripper::File(module->debug_file());
|
||||||
auto debugIdentifier = module->debug_identifier();
|
auto debugIdentifier = module->debug_identifier();
|
||||||
printf(CRPRE "M|%s|%s" CRPOST, debugFile.c_str(), debugIdentifier.c_str());
|
printf("|M|%s|%s", debugFile.c_str(), debugIdentifier.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
for (int frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
@ -135,15 +167,13 @@ int main(int argc, char *argv[])
|
|||||||
auto moduleIndex = moduleMap[frame->module];
|
auto moduleIndex = moduleMap[frame->module];
|
||||||
auto moduleOffset = frame->ReturnAddress() - frame->module->base_address();
|
auto moduleOffset = frame->ReturnAddress() - frame->module->base_address();
|
||||||
|
|
||||||
printf(CRPRE "F|%d|%x" CRPOST, moduleIndex, (intptr_t)moduleOffset);
|
printf("|F|%d|%x", moduleIndex, (intptr_t)moduleOffset);
|
||||||
} else {
|
} else {
|
||||||
printf(CRPRE "F|%d|%x" CRPOST, -1, (intptr_t)frame->ReturnAddress());
|
printf("|F|%d|%x", -1, (intptr_t)frame->ReturnAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ONELINE
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateCrash) {
|
if (generateCrash) {
|
||||||
|
Loading…
Reference in New Issue
Block a user