Implement CrashGeneration{Client,Server} for OOP dump generation on OS X, enable OOP dump generation in ExceptionHandler
R=mark at http://breakpad.appspot.com/146001 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@646 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
863aa2a74a
commit
315fd78199
13 changed files with 984 additions and 12 deletions
|
@ -51,6 +51,9 @@
|
|||
8B4BDABE12012CEF009C7060 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4BDAA7120124EA009C7060 /* libcrypto.dylib */; };
|
||||
8B4BDAC512012D05009C7060 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4BDAA7120124EA009C7060 /* libcrypto.dylib */; };
|
||||
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
|
||||
D24BBBFD121050F000F3D417 /* breakpadUtilities.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F92C563C0ECD10B3009BE4BA /* breakpadUtilities.dylib */; };
|
||||
D24BBD291211EDB100F3D417 /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; };
|
||||
D24BBD321212CACF00F3D417 /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; };
|
||||
D2A5DD301188633800081F03 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; };
|
||||
D2A5DD401188640400081F03 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; };
|
||||
D2A5DD411188642E00081F03 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; };
|
||||
|
@ -59,6 +62,34 @@
|
|||
D2F9A44012131F65002747C1 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A43E12131F65002747C1 /* gtest_main.cc */; };
|
||||
D2F9A44112131F65002747C1 /* gtest-all.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A43F12131F65002747C1 /* gtest-all.cc */; };
|
||||
D2F9A44412131F84002747C1 /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2F9A41512131EF0002747C1 /* libgtest.a */; };
|
||||
D2F9A4C9121336C7002747C1 /* client_info.h in Headers */ = {isa = PBXBuildFile; fileRef = D2F9A4C4121336C7002747C1 /* client_info.h */; };
|
||||
D2F9A4CA121336C7002747C1 /* crash_generation_client.h in Headers */ = {isa = PBXBuildFile; fileRef = D2F9A4C5121336C7002747C1 /* crash_generation_client.h */; };
|
||||
D2F9A4CB121336C7002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; };
|
||||
D2F9A4CC121336C7002747C1 /* crash_generation_server.h in Headers */ = {isa = PBXBuildFile; fileRef = D2F9A4C7121336C7002747C1 /* crash_generation_server.h */; };
|
||||
D2F9A4CD121336C7002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; };
|
||||
D2F9A4DF12133AD9002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; };
|
||||
D2F9A4E012133AD9002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; };
|
||||
D2F9A4E112133AE2002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; };
|
||||
D2F9A4E212133AE2002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; };
|
||||
D2F9A52E121383A1002747C1 /* crash_generation_client.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */; };
|
||||
D2F9A52F121383A1002747C1 /* crash_generation_server.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */; };
|
||||
D2F9A530121383A1002747C1 /* MachIPC.mm in Sources */ = {isa = PBXBuildFile; fileRef = F92C53790ECCE635009BE4BA /* MachIPC.mm */; };
|
||||
D2F9A531121383A1002747C1 /* breakpad_nlist_64.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53690ECCE3FD009BE4BA /* breakpad_nlist_64.cc */; };
|
||||
D2F9A532121383A1002747C1 /* dynamic_images.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536B0ECCE3FD009BE4BA /* dynamic_images.cc */; };
|
||||
D2F9A533121383A1002747C1 /* exception_handler.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536D0ECCE3FD009BE4BA /* exception_handler.cc */; };
|
||||
D2F9A534121383A1002747C1 /* minidump_generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C536F0ECCE3FD009BE4BA /* minidump_generator.cc */; };
|
||||
D2F9A535121383A1002747C1 /* minidump_file_writer.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C538F0ECCE70A009BE4BA /* minidump_file_writer.cc */; };
|
||||
D2F9A536121383A1002747C1 /* convert_UTF.c in Sources */ = {isa = PBXBuildFile; fileRef = F92C53870ECCE6C0009BE4BA /* convert_UTF.c */; };
|
||||
D2F9A537121383A1002747C1 /* string_conversion.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53850ECCE6AD009BE4BA /* string_conversion.cc */; };
|
||||
D2F9A538121383A1002747C1 /* file_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53740ECCE635009BE4BA /* file_id.cc */; };
|
||||
D2F9A539121383A1002747C1 /* macho_id.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537A0ECCE635009BE4BA /* macho_id.cc */; };
|
||||
D2F9A53A121383A1002747C1 /* macho_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537C0ECCE635009BE4BA /* macho_utilities.cc */; };
|
||||
D2F9A53B121383A1002747C1 /* macho_walker.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C537E0ECCE635009BE4BA /* macho_walker.cc */; };
|
||||
D2F9A53C121383A1002747C1 /* string_utilities.cc in Sources */ = {isa = PBXBuildFile; fileRef = F92C53820ECCE635009BE4BA /* string_utilities.cc */; };
|
||||
D2F9A53F121383A1002747C1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0867D69BFE84028FC02AAC07 /* Foundation.framework */; };
|
||||
D2F9A540121383A1002747C1 /* libcrypto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8B4BDAA7120124EA009C7060 /* libcrypto.dylib */; };
|
||||
D2F9A541121383A1002747C1 /* libgtest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D2F9A41512131EF0002747C1 /* libgtest.a */; };
|
||||
D2F9A553121383DC002747C1 /* crash_generation_server_test.cc in Sources */ = {isa = PBXBuildFile; fileRef = D2F9A4CE121336F7002747C1 /* crash_generation_server_test.cc */; };
|
||||
F91AF5D00FD60393009D8BE2 /* BreakpadFramework_Test.mm in Sources */ = {isa = PBXBuildFile; fileRef = F91AF5CF0FD60393009D8BE2 /* BreakpadFramework_Test.mm */; };
|
||||
F91AF6210FD60784009D8BE2 /* Breakpad.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* Breakpad.framework */; };
|
||||
F9286B3A0F7EB25800A4DCC8 /* InspectorMain.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9286B390F7EB25800A4DCC8 /* InspectorMain.mm */; };
|
||||
|
@ -280,9 +311,23 @@
|
|||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D2F9A41412131EF0002747C1 /* gtest */;
|
||||
remoteGlobalIDString = D2F9A41412131EF0002747C1;
|
||||
remoteInfo = gtest;
|
||||
};
|
||||
D2F9A52C121383A1002747C1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D2F9A41412131EF0002747C1;
|
||||
remoteInfo = gtest;
|
||||
};
|
||||
D2F9A5DE12142A6A002747C1 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = D2F9A52A121383A1002747C1;
|
||||
remoteInfo = crash_generation_server_test;
|
||||
};
|
||||
F91AF6370FD60A74009D8BE2 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
|
||||
|
@ -467,6 +512,13 @@
|
|||
D2F9A43C12131F55002747C1 /* gmock-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gmock-all.cc"; path = "../../testing/src/gmock-all.cc"; sourceTree = SOURCE_ROOT; };
|
||||
D2F9A43E12131F65002747C1 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gtest_main.cc; path = ../../testing/gtest/src/gtest_main.cc; sourceTree = "<group>"; };
|
||||
D2F9A43F12131F65002747C1 /* gtest-all.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "gtest-all.cc"; path = "../../testing/gtest/src/gtest-all.cc"; sourceTree = "<group>"; };
|
||||
D2F9A4C4121336C7002747C1 /* client_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = client_info.h; path = crash_generation/client_info.h; sourceTree = "<group>"; };
|
||||
D2F9A4C5121336C7002747C1 /* crash_generation_client.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crash_generation_client.h; path = crash_generation/crash_generation_client.h; sourceTree = "<group>"; };
|
||||
D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash_generation_client.cc; path = crash_generation/crash_generation_client.cc; sourceTree = "<group>"; };
|
||||
D2F9A4C7121336C7002747C1 /* crash_generation_server.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crash_generation_server.h; path = crash_generation/crash_generation_server.h; sourceTree = "<group>"; };
|
||||
D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash_generation_server.cc; path = crash_generation/crash_generation_server.cc; sourceTree = "<group>"; };
|
||||
D2F9A4CE121336F7002747C1 /* crash_generation_server_test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = crash_generation_server_test.cc; path = tests/crash_generation_server_test.cc; sourceTree = "<group>"; };
|
||||
D2F9A546121383A1002747C1 /* crash_generation_server_test */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = crash_generation_server_test; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DE43467411C72855004F095F /* da */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = da; path = sender/da.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
DE43467511C72857004F095F /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = sender/de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
DE43467611C7285B004F095F /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = sender/es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
|
@ -589,6 +641,16 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2F9A53E121383A1002747C1 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D2F9A53F121383A1002747C1 /* Foundation.framework in Frameworks */,
|
||||
D2F9A540121383A1002747C1 /* libcrypto.dylib in Frameworks */,
|
||||
D2F9A541121383A1002747C1 /* libgtest.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F92C53520ECCE349009BE4BA /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -661,6 +723,7 @@
|
|||
F91AF6210FD60784009D8BE2 /* Breakpad.framework in Frameworks */,
|
||||
8B3101EA11F0CDE300FCF3E4 /* SenTestingKit.framework in Frameworks */,
|
||||
8B3102EB11F0D78000FCF3E4 /* Foundation.framework in Frameworks */,
|
||||
D24BBBFD121050F000F3D417 /* breakpadUtilities.dylib in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -680,6 +743,7 @@
|
|||
F93DE2D10F82A67300608B94 /* minidump_file_writer_unittest */,
|
||||
F93DE32C0F82C55600608B94 /* handler_test */,
|
||||
D2F9A41512131EF0002747C1 /* libgtest.a */,
|
||||
D2F9A546121383A1002747C1 /* crash_generation_server_test */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -814,6 +878,11 @@
|
|||
F92C53B50ECCE799009BE4BA /* crash_generation */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2F9A4C4121336C7002747C1 /* client_info.h */,
|
||||
D2F9A4C5121336C7002747C1 /* crash_generation_client.h */,
|
||||
D2F9A4C6121336C7002747C1 /* crash_generation_client.cc */,
|
||||
D2F9A4C7121336C7002747C1 /* crash_generation_server.h */,
|
||||
D2F9A4C8121336C7002747C1 /* crash_generation_server.cc */,
|
||||
F9286B380F7EB25800A4DCC8 /* Inspector.h */,
|
||||
F9286B390F7EB25800A4DCC8 /* InspectorMain.mm */,
|
||||
F92C53B70ECCE7B3009BE4BA /* Inspector.mm */,
|
||||
|
@ -917,6 +986,7 @@
|
|||
F9C77DDF0F7DD7CF0045F7DB /* tests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2F9A4CE121336F7002747C1 /* crash_generation_server_test.cc */,
|
||||
D2F9A3D41212F87C002747C1 /* exception_handler_test.cc */,
|
||||
F9C77DE00F7DD7E30045F7DB /* SimpleStringDictionaryTest.h */,
|
||||
F9C77DE10F7DD7E30045F7DB /* SimpleStringDictionaryTest.mm */,
|
||||
|
@ -943,6 +1013,9 @@
|
|||
files = (
|
||||
F92C55D00ECD0064009BE4BA /* Breakpad.h in Headers */,
|
||||
F92C56330ECD0DF1009BE4BA /* OnDemandServer.h in Headers */,
|
||||
D2F9A4C9121336C7002747C1 /* client_info.h in Headers */,
|
||||
D2F9A4CA121336C7002747C1 /* crash_generation_client.h in Headers */,
|
||||
D2F9A4CC121336C7002747C1 /* crash_generation_server.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1003,6 +1076,23 @@
|
|||
productReference = D2F9A41512131EF0002747C1 /* libgtest.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
D2F9A52A121383A1002747C1 /* crash_generation_server_test */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = D2F9A542121383A1002747C1 /* Build configuration list for PBXNativeTarget "crash_generation_server_test" */;
|
||||
buildPhases = (
|
||||
D2F9A52D121383A1002747C1 /* Sources */,
|
||||
D2F9A53E121383A1002747C1 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
D2F9A52B121383A1002747C1 /* PBXTargetDependency */,
|
||||
);
|
||||
name = crash_generation_server_test;
|
||||
productName = handler_test;
|
||||
productReference = D2F9A546121383A1002747C1 /* crash_generation_server_test */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
F92C53530ECCE349009BE4BA /* Inspector */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F92C53580ECCE36D009BE4BA /* Build configuration list for PBXNativeTarget "Inspector" */;
|
||||
|
@ -1138,6 +1228,7 @@
|
|||
F93DE2FC0F82C3C600608B94 /* PBXTargetDependency */,
|
||||
F93DE3700F82CC1300608B94 /* PBXTargetDependency */,
|
||||
F91AF6380FD60A74009D8BE2 /* PBXTargetDependency */,
|
||||
D2F9A5DF12142A6A002747C1 /* PBXTargetDependency */,
|
||||
);
|
||||
name = UnitTests;
|
||||
productName = UnitTests;
|
||||
|
@ -1196,6 +1287,7 @@
|
|||
F93DE2D00F82A67300608B94 /* minidump_file_writer_unittest */,
|
||||
F93DE32B0F82C55600608B94 /* handler_test */,
|
||||
D2F9A41412131EF0002747C1 /* gtest */,
|
||||
D2F9A52A121383A1002747C1 /* crash_generation_server_test */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -1412,7 +1504,7 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n\necho running minidump generator tests...\n\"${BUILT_PRODUCTS_DIR}/generator_test\"\necho Running exception handler tests...\n\"${BUILT_PRODUCTS_DIR}/handler_test\"\n";
|
||||
shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n\necho running minidump generator tests...\n\"${BUILT_PRODUCTS_DIR}/generator_test\"\necho Running exception handler tests...\n\"${BUILT_PRODUCTS_DIR}/handler_test\"\necho Running crash generation server tests...\n\"${BUILT_PRODUCTS_DIR}/crash_generation_server_test\"\n";
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
|
@ -1425,6 +1517,8 @@
|
|||
F92C56630ECD1179009BE4BA /* exception_handler.cc in Sources */,
|
||||
F92C55D10ECD0064009BE4BA /* Breakpad.mm in Sources */,
|
||||
F92C56340ECD0DF1009BE4BA /* OnDemandServer.mm in Sources */,
|
||||
D2F9A4CB121336C7002747C1 /* crash_generation_client.cc in Sources */,
|
||||
D2F9A4CD121336C7002747C1 /* crash_generation_server.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -1438,6 +1532,29 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
D2F9A52D121383A1002747C1 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D2F9A553121383DC002747C1 /* crash_generation_server_test.cc in Sources */,
|
||||
D2F9A52E121383A1002747C1 /* crash_generation_client.cc in Sources */,
|
||||
D2F9A52F121383A1002747C1 /* crash_generation_server.cc in Sources */,
|
||||
D2F9A530121383A1002747C1 /* MachIPC.mm in Sources */,
|
||||
D2F9A531121383A1002747C1 /* breakpad_nlist_64.cc in Sources */,
|
||||
D2F9A532121383A1002747C1 /* dynamic_images.cc in Sources */,
|
||||
D2F9A533121383A1002747C1 /* exception_handler.cc in Sources */,
|
||||
D2F9A534121383A1002747C1 /* minidump_generator.cc in Sources */,
|
||||
D2F9A535121383A1002747C1 /* minidump_file_writer.cc in Sources */,
|
||||
D2F9A536121383A1002747C1 /* convert_UTF.c in Sources */,
|
||||
D2F9A537121383A1002747C1 /* string_conversion.cc in Sources */,
|
||||
D2F9A538121383A1002747C1 /* file_id.cc in Sources */,
|
||||
D2F9A539121383A1002747C1 /* macho_id.cc in Sources */,
|
||||
D2F9A53A121383A1002747C1 /* macho_utilities.cc in Sources */,
|
||||
D2F9A53B121383A1002747C1 /* macho_walker.cc in Sources */,
|
||||
D2F9A53C121383A1002747C1 /* string_utilities.cc in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
F92C53510ECCE349009BE4BA /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -1481,6 +1598,9 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D2F9A4DF12133AD9002747C1 /* crash_generation_client.cc in Sources */,
|
||||
D2F9A4E012133AD9002747C1 /* crash_generation_server.cc in Sources */,
|
||||
D24BBD291211EDB100F3D417 /* MachIPC.mm in Sources */,
|
||||
D2A5DD401188640400081F03 /* breakpad_nlist_64.cc in Sources */,
|
||||
F93803CD0F8083B7004D428B /* dynamic_images.cc in Sources */,
|
||||
F93803CE0F8083B7004D428B /* exception_handler.cc in Sources */,
|
||||
|
@ -1512,6 +1632,9 @@
|
|||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
D2F9A4E112133AE2002747C1 /* crash_generation_client.cc in Sources */,
|
||||
D2F9A4E212133AE2002747C1 /* crash_generation_server.cc in Sources */,
|
||||
D24BBD321212CACF00F3D417 /* MachIPC.mm in Sources */,
|
||||
D2A5DD411188642E00081F03 /* breakpad_nlist_64.cc in Sources */,
|
||||
F93DE3350F82C66B00608B94 /* dynamic_images.cc in Sources */,
|
||||
F93DE3360F82C66B00608B94 /* exception_handler.cc in Sources */,
|
||||
|
@ -1587,6 +1710,16 @@
|
|||
target = D2F9A41412131EF0002747C1 /* gtest */;
|
||||
targetProxy = D2F9A44212131F80002747C1 /* PBXContainerItemProxy */;
|
||||
};
|
||||
D2F9A52B121383A1002747C1 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = D2F9A41412131EF0002747C1 /* gtest */;
|
||||
targetProxy = D2F9A52C121383A1002747C1 /* PBXContainerItemProxy */;
|
||||
};
|
||||
D2F9A5DF12142A6A002747C1 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = D2F9A52A121383A1002747C1 /* crash_generation_server_test */;
|
||||
targetProxy = D2F9A5DE12142A6A002747C1 /* PBXContainerItemProxy */;
|
||||
};
|
||||
F91AF6380FD60A74009D8BE2 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 8DC2EF4F0486A6940098B216 /* Breakpad */;
|
||||
|
@ -1821,6 +1954,51 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
D2F9A543121383A1002747C1 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../..,
|
||||
../../testing,
|
||||
../../testing/include,
|
||||
../../testing/gtest,
|
||||
../../testing/gtest/include,
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\"$(SRCROOT)/build/Debug\"",
|
||||
);
|
||||
PRODUCT_NAME = crash_generation_server_test;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
D2F9A544121383A1002747C1 /* Debug With Code Coverage */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
HEADER_SEARCH_PATHS = ../..;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\\\"$(SRCROOT)/build/Debug\\\"",
|
||||
);
|
||||
PRODUCT_NAME = handler_test;
|
||||
};
|
||||
name = "Debug With Code Coverage";
|
||||
};
|
||||
D2F9A545121383A1002747C1 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
HEADER_SEARCH_PATHS = ../..;
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"\\\"$(SRCROOT)/build/Debug\\\"",
|
||||
);
|
||||
PRODUCT_NAME = handler_test;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
F92C53560ECCE34A009BE4BA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -1921,6 +2099,8 @@
|
|||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
GCC_INLINES_ARE_PRIVATE_EXTERN = NO;
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
HEADER_SEARCH_PATHS = (
|
||||
../..,
|
||||
../../testing,
|
||||
|
@ -2028,6 +2208,7 @@
|
|||
"\"$(DEVELOPER_FRAMEWORKS_DIR)\"",
|
||||
);
|
||||
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||
HEADER_SEARCH_PATHS = ../..;
|
||||
INFOPLIST_FILE = "UnitTests-Info.plist";
|
||||
PRODUCT_NAME = UnitTests;
|
||||
WRAPPER_EXTENSION = octest;
|
||||
|
@ -2155,6 +2336,16 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
D2F9A542121383A1002747C1 /* Build configuration list for PBXNativeTarget "crash_generation_server_test" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
D2F9A543121383A1002747C1 /* Debug */,
|
||||
D2F9A544121383A1002747C1 /* Debug With Code Coverage */,
|
||||
D2F9A545121383A1002747C1 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
F92C53580ECCE36D009BE4BA /* Build configuration list for PBXNativeTarget "Inspector" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
|
43
src/client/mac/crash_generation/client_info.h
Normal file
43
src/client/mac/crash_generation/client_info.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
// Copyright (c) 2010 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_
|
||||
#define CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
struct ClientInfo {
|
||||
int exception_type;
|
||||
int exception_code;
|
||||
int exception_subcode;
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // CLIENT_MAC_CRASH_GENERATION_CLIENT_INFO_H_
|
74
src/client/mac/crash_generation/crash_generation_client.cc
Normal file
74
src/client/mac/crash_generation/crash_generation_client.cc
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2010 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "client/mac/crash_generation/crash_generation_client.h"
|
||||
|
||||
#include "client/mac/crash_generation/client_info.h"
|
||||
#include "client/mac/crash_generation/crash_generation_server.h"
|
||||
#include "common/mac/MachIPC.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
bool CrashGenerationClient::RequestDumpForException(
|
||||
int exception_type,
|
||||
int exception_code,
|
||||
int exception_subcode,
|
||||
mach_port_t crashing_thread) {
|
||||
// The server will send a message to this port indicating that it
|
||||
// has finished its work.
|
||||
ReceivePort acknowledge_port;
|
||||
|
||||
MachSendMessage message(kDumpRequestMessage);
|
||||
message.AddDescriptor(mach_task_self()); // this task
|
||||
message.AddDescriptor(crashing_thread); // crashing thread
|
||||
message.AddDescriptor(mach_thread_self()); // handler thread
|
||||
message.AddDescriptor(acknowledge_port.GetPort()); // message receive port
|
||||
|
||||
ClientInfo info;
|
||||
info.exception_type = exception_type;
|
||||
info.exception_code = exception_code;
|
||||
info.exception_subcode = exception_subcode;
|
||||
message.SetData(&info, sizeof(info));
|
||||
|
||||
const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000;
|
||||
kern_return_t result = sender_.SendMessage(message, kSendTimeoutMs);
|
||||
if (result != KERN_SUCCESS)
|
||||
return false;
|
||||
|
||||
// Give the server slightly longer to reply since it has to
|
||||
// inspect this task and write the minidump.
|
||||
const mach_msg_timeout_t kReceiveTimeoutMs = 5 * 1000;
|
||||
MachReceiveMessage acknowledge_message;
|
||||
result = acknowledge_port.WaitForMessage(&acknowledge_message,
|
||||
kReceiveTimeoutMs);
|
||||
|
||||
return result == KERN_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
65
src/client/mac/crash_generation/crash_generation_client.h
Normal file
65
src/client/mac/crash_generation/crash_generation_client.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Copyright (c) 2010 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
||||
#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
||||
|
||||
#include "common/mac/MachIPC.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
class CrashGenerationClient {
|
||||
public:
|
||||
explicit CrashGenerationClient(const char* mach_port_name)
|
||||
: sender_(mach_port_name) {
|
||||
}
|
||||
|
||||
// Request the crash server to generate a dump.
|
||||
//
|
||||
// Return true if the dump was successful; false otherwise.
|
||||
bool RequestDumpForException(int exception_type,
|
||||
int exception_code,
|
||||
int exception_subcode,
|
||||
mach_port_t crashing_thread);
|
||||
|
||||
bool RequestDump() {
|
||||
return RequestDumpForException(0, 0, 0, MACH_PORT_NULL);
|
||||
}
|
||||
|
||||
private:
|
||||
MachPortSender sender_;
|
||||
|
||||
// Prevent copy construction and assignment.
|
||||
CrashGenerationClient(const CrashGenerationClient&);
|
||||
CrashGenerationClient& operator=(const CrashGenerationClient&);
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_CLIENT_H_
|
158
src/client/mac/crash_generation/crash_generation_server.cc
Normal file
158
src/client/mac/crash_generation/crash_generation_server.cc
Normal file
|
@ -0,0 +1,158 @@
|
|||
// Copyright (c) 2010 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "client/mac/crash_generation/crash_generation_server.h"
|
||||
|
||||
#include "client/mac/crash_generation/client_info.h"
|
||||
#include "client/mac/handler/minidump_generator.h"
|
||||
#include "common/mac/scoped_task_suspend-inl.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
CrashGenerationServer::CrashGenerationServer(
|
||||
const char *mach_port_name,
|
||||
OnClientDumpRequestCallback dump_callback,
|
||||
void *dump_context,
|
||||
OnClientExitingCallback exit_callback,
|
||||
void *exit_context,
|
||||
bool generate_dumps,
|
||||
const std::string &dump_path)
|
||||
: dump_callback_(dump_callback),
|
||||
dump_context_(dump_context),
|
||||
exit_callback_(exit_callback),
|
||||
exit_context_(exit_context),
|
||||
generate_dumps_(generate_dumps),
|
||||
dump_dir_(dump_path.empty() ? "/tmp" : dump_path),
|
||||
started_(false),
|
||||
receive_port_(mach_port_name),
|
||||
mach_port_name_(mach_port_name) {
|
||||
}
|
||||
|
||||
CrashGenerationServer::~CrashGenerationServer() {
|
||||
if (started_)
|
||||
Stop();
|
||||
}
|
||||
|
||||
bool CrashGenerationServer::Start() {
|
||||
int thread_create_result = pthread_create(&server_thread_, NULL,
|
||||
&WaitForMessages, this);
|
||||
started_ = thread_create_result == 0;
|
||||
return started_;
|
||||
}
|
||||
|
||||
bool CrashGenerationServer::Stop() {
|
||||
if (!started_)
|
||||
return false;
|
||||
|
||||
// Send a quit message to the background thread, and then join it.
|
||||
MachPortSender sender(mach_port_name_.c_str());
|
||||
MachSendMessage quit_message(kQuitMessage);
|
||||
const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000;
|
||||
kern_return_t result = sender.SendMessage(quit_message, kSendTimeoutMs);
|
||||
if (result == KERN_SUCCESS) {
|
||||
int thread_join_result = pthread_join(server_thread_, NULL);
|
||||
started_ = thread_join_result != 0;
|
||||
}
|
||||
|
||||
return !started_;
|
||||
}
|
||||
|
||||
// static
|
||||
void *CrashGenerationServer::WaitForMessages(void *server) {
|
||||
CrashGenerationServer *self =
|
||||
reinterpret_cast<CrashGenerationServer*>(server);
|
||||
while (self->WaitForOneMessage()) {}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool CrashGenerationServer::WaitForOneMessage() {
|
||||
MachReceiveMessage message;
|
||||
kern_return_t result = receive_port_.WaitForMessage(&message,
|
||||
MACH_MSG_TIMEOUT_NONE);
|
||||
if (result == KERN_SUCCESS) {
|
||||
switch (message.GetMessageID()) {
|
||||
case kDumpRequestMessage: {
|
||||
ClientInfo &info = (ClientInfo &)*message.GetData();
|
||||
|
||||
mach_port_t remote_task = message.GetTranslatedPort(0);
|
||||
mach_port_t crashing_thread = message.GetTranslatedPort(1);
|
||||
mach_port_t handler_thread = message.GetTranslatedPort(2);
|
||||
mach_port_t ack_port = message.GetTranslatedPort(3);
|
||||
|
||||
bool result;
|
||||
std::string dump_path;
|
||||
if (generate_dumps_) {
|
||||
ScopedTaskSuspend suspend(remote_task);
|
||||
|
||||
MinidumpGenerator generator(remote_task, handler_thread);
|
||||
dump_path = generator.UniqueNameInDirectory(dump_dir_, NULL);
|
||||
|
||||
if (info.exception_type && info.exception_code) {
|
||||
generator.SetExceptionInformation(info.exception_type,
|
||||
info.exception_code,
|
||||
info.exception_subcode,
|
||||
crashing_thread);
|
||||
}
|
||||
result = generator.Write(dump_path.c_str());
|
||||
} else {
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (result && dump_callback_) {
|
||||
dump_callback_(dump_context_, info, dump_path);
|
||||
}
|
||||
|
||||
// TODO(ted): support a way for the client to send additional data,
|
||||
// perhaps with a callback so users of the server can read the data
|
||||
// themselves?
|
||||
|
||||
if (ack_port != MACH_PORT_DEAD && ack_port != MACH_PORT_NULL) {
|
||||
MachPortSender sender(ack_port);
|
||||
MachSendMessage ack_message(kAcknowledgementMessage);
|
||||
const mach_msg_timeout_t kSendTimeoutMs = 2 * 1000;
|
||||
|
||||
sender.SendMessage(ack_message, kSendTimeoutMs);
|
||||
}
|
||||
|
||||
if (exit_callback_) {
|
||||
exit_callback_(exit_context_, info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kQuitMessage:
|
||||
return false;
|
||||
}
|
||||
} else { // result != KERN_SUCCESS
|
||||
mach_error("WaitForMessage", result);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace google_breakpad
|
132
src/client/mac/crash_generation/crash_generation_server.h
Normal file
132
src/client/mac/crash_generation/crash_generation_server.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
// Copyright (c) 2010 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#ifndef GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
|
||||
#define GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/mac/MachIPC.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
class ClientInfo;
|
||||
|
||||
// Messages the server can read via its mach port
|
||||
enum {
|
||||
kDumpRequestMessage = 1,
|
||||
kAcknowledgementMessage = 2,
|
||||
kQuitMessage = 3
|
||||
};
|
||||
|
||||
class CrashGenerationServer {
|
||||
public:
|
||||
// WARNING: callbacks may be invoked on a different thread
|
||||
// than that which creates the CrashGenerationServer. They must
|
||||
// be thread safe.
|
||||
typedef void (*OnClientDumpRequestCallback)(void *context,
|
||||
const ClientInfo &client_info,
|
||||
const std::string &file_path);
|
||||
|
||||
typedef void (*OnClientExitingCallback)(void *context,
|
||||
const ClientInfo &client_info);
|
||||
|
||||
// Create an instance with the given parameters.
|
||||
//
|
||||
// mach_port_name: Named server port to listen on.
|
||||
// dump_callback: Callback for a client crash dump request.
|
||||
// dump_context: Context for client crash dump request callback.
|
||||
// exit_callback: Callback for client process exit.
|
||||
// exit_context: Context for client exit callback.
|
||||
// generate_dumps: Whether to automatically generate dumps.
|
||||
// Client code of this class might want to generate dumps explicitly
|
||||
// in the crash dump request callback. In that case, false can be
|
||||
// passed for this parameter.
|
||||
// dump_path: Path for generating dumps; required only if true is
|
||||
// passed for generateDumps parameter; NULL can be passed otherwise.
|
||||
CrashGenerationServer(const char *mach_port_name,
|
||||
OnClientDumpRequestCallback dump_callback,
|
||||
void *dump_context,
|
||||
OnClientExitingCallback exit_callback,
|
||||
void *exit_context,
|
||||
bool generate_dumps,
|
||||
const std::string &dump_path);
|
||||
|
||||
~CrashGenerationServer();
|
||||
|
||||
// Perform initialization steps needed to start listening to clients.
|
||||
//
|
||||
// Return true if initialization is successful; false otherwise.
|
||||
bool Start();
|
||||
|
||||
// Stop the server.
|
||||
bool Stop();
|
||||
|
||||
private:
|
||||
// Return a unique filename at which a minidump can be written.
|
||||
bool MakeMinidumpFilename(std::string &outFilename);
|
||||
|
||||
// Loop reading client messages and responding to them until
|
||||
// a quit message is received.
|
||||
static void *WaitForMessages(void *server);
|
||||
|
||||
// Wait for a single client message and respond to it. Returns false
|
||||
// if a quit message was received or if an error occurred.
|
||||
bool WaitForOneMessage();
|
||||
|
||||
OnClientDumpRequestCallback dump_callback_;
|
||||
void *dump_context_;
|
||||
|
||||
OnClientExitingCallback exit_callback_;
|
||||
void *exit_context_;
|
||||
|
||||
bool generate_dumps_;
|
||||
|
||||
std::string dump_dir_;
|
||||
|
||||
bool started_;
|
||||
|
||||
// The mach port that receives requests to dump from child processes.
|
||||
ReceivePort receive_port_;
|
||||
|
||||
// The name of the mach port. Stored so the Stop method can message
|
||||
// the background thread to shut it down.
|
||||
std::string mach_port_name_;
|
||||
|
||||
// The thread that waits on the receive port.
|
||||
pthread_t server_thread_;
|
||||
|
||||
// Disable copy constructor and operator=.
|
||||
CrashGenerationServer(const CrashGenerationServer&);
|
||||
CrashGenerationServer& operator=(const CrashGenerationServer&);
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // GOOGLE_BREAKPAD_CLIENT_MAC_CRASH_GENERATION_CRASH_GENERATION_SERVER_H_
|
|
@ -221,7 +221,8 @@ ExceptionHandler::ExceptionHandler(const string &dump_path,
|
|||
FilterCallback filter,
|
||||
MinidumpCallback callback,
|
||||
void *callback_context,
|
||||
bool install_handler)
|
||||
bool install_handler,
|
||||
const char *port_name)
|
||||
: dump_path_(),
|
||||
filter_(filter),
|
||||
callback_(callback),
|
||||
|
@ -237,6 +238,8 @@ ExceptionHandler::ExceptionHandler(const string &dump_path,
|
|||
// This will update to the ID and C-string pointers
|
||||
set_dump_path(dump_path);
|
||||
MinidumpGenerator::GatherSystemInformation();
|
||||
if (port_name)
|
||||
crash_generation_client_.reset(new CrashGenerationClient(port_name));
|
||||
Setup(install_handler);
|
||||
}
|
||||
|
||||
|
@ -293,7 +296,8 @@ bool ExceptionHandler::WriteMinidump() {
|
|||
bool ExceptionHandler::WriteMinidump(const string &dump_path,
|
||||
MinidumpCallback callback,
|
||||
void *callback_context) {
|
||||
ExceptionHandler handler(dump_path, NULL, callback, callback_context, false);
|
||||
ExceptionHandler handler(dump_path, NULL, callback, callback_context, false,
|
||||
NULL);
|
||||
return handler.WriteMinidump();
|
||||
}
|
||||
|
||||
|
@ -312,6 +316,18 @@ bool ExceptionHandler::WriteMinidumpWithException(int exception_type,
|
|||
if (exception_type && exception_code)
|
||||
_exit(exception_type);
|
||||
}
|
||||
} else if (IsOutOfProcess()) {
|
||||
if (exception_type && exception_code) {
|
||||
// If this is a real exception, give the filter (if any) a chance to
|
||||
// decide if this should be sent.
|
||||
if (filter_ && !filter_(callback_context_))
|
||||
return false;
|
||||
return crash_generation_client_->RequestDumpForException(
|
||||
exception_type,
|
||||
exception_code,
|
||||
exception_subcode,
|
||||
thread_name);
|
||||
}
|
||||
} else {
|
||||
string minidump_id;
|
||||
|
||||
|
@ -321,7 +337,7 @@ bool ExceptionHandler::WriteMinidumpWithException(int exception_type,
|
|||
MinidumpGenerator md;
|
||||
if (exception_type && exception_code) {
|
||||
// If this is a real exception, give the filter (if any) a chance to
|
||||
// decided if this should be sent
|
||||
// decide if this should be sent.
|
||||
if (filter_ && !filter_(callback_context_))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -40,6 +40,9 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "client/mac/crash_generation/crash_generation_client.h"
|
||||
#include "processor/scoped_ptr.h"
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
using std::string;
|
||||
|
@ -86,9 +89,12 @@ class ExceptionHandler {
|
|||
// If install_handler is true, then a minidump will be written whenever
|
||||
// an unhandled exception occurs. If it is false, minidumps will only
|
||||
// be written when WriteMinidump is called.
|
||||
// If port_name is non-NULL, attempt to perform out-of-process dump generation
|
||||
// If port_name is NULL, in-process dump generation will be used.
|
||||
ExceptionHandler(const string &dump_path,
|
||||
FilterCallback filter, MinidumpCallback callback,
|
||||
void *callback_context, bool install_handler);
|
||||
void *callback_context, bool install_handler,
|
||||
const char *port_name);
|
||||
|
||||
// A special constructor if we want to bypass minidump writing and
|
||||
// simply get a callback with the exception information.
|
||||
|
@ -115,6 +121,11 @@ class ExceptionHandler {
|
|||
static bool WriteMinidump(const string &dump_path, MinidumpCallback callback,
|
||||
void *callback_context);
|
||||
|
||||
// Returns whether out-of-process dump generation is used or not.
|
||||
bool IsOutOfProcess() const {
|
||||
return crash_generation_client_.get() != NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
// Install the mach exception handler
|
||||
bool InstallHandler();
|
||||
|
@ -206,6 +217,9 @@ class ExceptionHandler {
|
|||
|
||||
// True, if we're using the mutext to indicate when mindump writing occurs
|
||||
bool use_minidump_write_mutex_;
|
||||
|
||||
// Client for out-of-process dump generation.
|
||||
scoped_ptr<CrashGenerationClient> crash_generation_client_;
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
|
217
src/client/mac/tests/crash_generation_server_test.cc
Normal file
217
src/client/mac/tests/crash_generation_server_test.cc
Normal file
|
@ -0,0 +1,217 @@
|
|||
// Copyright (c) 2010, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// crash_generation_server_test.cc
|
||||
// Unit tests for CrashGenerationServer
|
||||
|
||||
#include <dirent.h>
|
||||
#include <glob.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "breakpad_googletest_includes.h"
|
||||
#include "client/mac/crash_generation/client_info.h"
|
||||
#include "client/mac/crash_generation/crash_generation_client.h"
|
||||
#include "client/mac/crash_generation/crash_generation_server.h"
|
||||
#include "client/mac/handler/exception_handler.h"
|
||||
#include "client/mac/tests/auto_tempdir.h"
|
||||
|
||||
namespace {
|
||||
using std::string;
|
||||
using google_breakpad::AutoTempDir;
|
||||
using google_breakpad::ClientInfo;
|
||||
using google_breakpad::CrashGenerationClient;
|
||||
using google_breakpad::CrashGenerationServer;
|
||||
using google_breakpad::ExceptionHandler;
|
||||
using testing::Test;
|
||||
|
||||
class CrashGenerationServerTest : public Test {
|
||||
public:
|
||||
// The port name to receive messages on
|
||||
char mach_port_name[128];
|
||||
// Filename of the last dump that was generated
|
||||
string last_dump_name;
|
||||
// A temp dir
|
||||
AutoTempDir temp_dir;
|
||||
// Counter just to ensure that we don't hit the same port again
|
||||
static int i;
|
||||
|
||||
void SetUp() {
|
||||
sprintf(mach_port_name,
|
||||
"com.google.breakpad.ServerTest.%d.%d", getpid(),
|
||||
CrashGenerationServerTest::i++);
|
||||
}
|
||||
};
|
||||
int CrashGenerationServerTest::i = 0;
|
||||
|
||||
// Test that starting and stopping a server works
|
||||
TEST_F(CrashGenerationServerTest, testStartStopServer) {
|
||||
CrashGenerationServer server(mach_port_name,
|
||||
NULL, // dump callback
|
||||
NULL, // dump context
|
||||
NULL, // exit callback
|
||||
NULL, // exit context
|
||||
false, // generate dumps
|
||||
""); // dump path
|
||||
ASSERT_TRUE(server.Start());
|
||||
ASSERT_TRUE(server.Stop());
|
||||
}
|
||||
|
||||
// Test that requesting a dump via CrashGenerationClient works
|
||||
// Test without actually dumping
|
||||
TEST_F(CrashGenerationServerTest, testRequestDumpNoDump) {
|
||||
CrashGenerationServer server(mach_port_name,
|
||||
NULL, // dump callback
|
||||
NULL, // dump context
|
||||
NULL, // exit callback
|
||||
NULL, // exit context
|
||||
false, // don't generate dumps
|
||||
temp_dir.path); // dump path
|
||||
ASSERT_TRUE(server.Start());
|
||||
|
||||
pid_t pid = fork();
|
||||
ASSERT_NE(-1, pid);
|
||||
if (pid == 0) {
|
||||
CrashGenerationClient client(mach_port_name);
|
||||
bool result = client.RequestDump();
|
||||
exit(result ? 0 : 1);
|
||||
}
|
||||
|
||||
int ret;
|
||||
ASSERT_EQ(pid, waitpid(pid, &ret, 0));
|
||||
EXPECT_TRUE(WIFEXITED(ret));
|
||||
EXPECT_EQ(0, WEXITSTATUS(ret));
|
||||
EXPECT_TRUE(server.Stop());
|
||||
// check that no minidump was written
|
||||
string pattern = temp_dir.path + "/*";
|
||||
glob_t dirContents;
|
||||
ret = glob(pattern.c_str(), GLOB_NOSORT, NULL, &dirContents);
|
||||
EXPECT_EQ(GLOB_NOMATCH, ret);
|
||||
if (ret != GLOB_NOMATCH)
|
||||
globfree(&dirContents);
|
||||
}
|
||||
|
||||
void dumpCallback(void *context, const ClientInfo &client_info,
|
||||
const std::string &file_path) {
|
||||
if (context) {
|
||||
CrashGenerationServerTest* self =
|
||||
reinterpret_cast<CrashGenerationServerTest*>(context);
|
||||
if (!file_path.empty())
|
||||
self->last_dump_name = file_path;
|
||||
}
|
||||
}
|
||||
|
||||
void *RequestDump(void *context) {
|
||||
CrashGenerationClient client((const char*)context);
|
||||
bool result = client.RequestDump();
|
||||
return (void*)(result ? 0 : 1);
|
||||
}
|
||||
|
||||
// Test that actually writing a minidump works
|
||||
TEST_F(CrashGenerationServerTest, testRequestDump) {
|
||||
CrashGenerationServer server(mach_port_name,
|
||||
dumpCallback, // dump callback
|
||||
this, // dump context
|
||||
NULL, // exit callback
|
||||
NULL, // exit context
|
||||
true, // generate dumps
|
||||
temp_dir.path); // dump path
|
||||
ASSERT_TRUE(server.Start());
|
||||
|
||||
pid_t pid = fork();
|
||||
ASSERT_NE(-1, pid);
|
||||
if (pid == 0) {
|
||||
// Have to spawn off a separate thread to request the dump,
|
||||
// because MinidumpGenerator assumes the handler thread is not
|
||||
// the only thread
|
||||
pthread_t thread;
|
||||
if (pthread_create(&thread, NULL, RequestDump, (void*)mach_port_name) != 0)
|
||||
exit(1);
|
||||
void* result;
|
||||
pthread_join(thread, &result);
|
||||
exit(reinterpret_cast<intptr_t>(result));
|
||||
}
|
||||
|
||||
int ret;
|
||||
ASSERT_EQ(pid, waitpid(pid, &ret, 0));
|
||||
EXPECT_TRUE(WIFEXITED(ret));
|
||||
EXPECT_EQ(0, WEXITSTATUS(ret));
|
||||
EXPECT_TRUE(server.Stop());
|
||||
// check that minidump was written
|
||||
ASSERT_FALSE(last_dump_name.empty());
|
||||
struct stat st;
|
||||
EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
|
||||
EXPECT_LT(0, st.st_size);
|
||||
}
|
||||
|
||||
static void Crasher() {
|
||||
int *a = (int*)0x42;
|
||||
|
||||
fprintf(stdout, "Going to crash...\n");
|
||||
fprintf(stdout, "A = %d", *a);
|
||||
}
|
||||
|
||||
// Test that crashing a child process with an OOP ExceptionHandler installed
|
||||
// results in a minidump being written by the CrashGenerationServer in
|
||||
// the parent.
|
||||
TEST_F(CrashGenerationServerTest, testChildProcessCrash) {
|
||||
CrashGenerationServer server(mach_port_name,
|
||||
dumpCallback, // dump callback
|
||||
this, // dump context
|
||||
NULL, // exit callback
|
||||
NULL, // exit context
|
||||
true, // generate dumps
|
||||
temp_dir.path); // dump path
|
||||
ASSERT_TRUE(server.Start());
|
||||
|
||||
pid_t pid = fork();
|
||||
ASSERT_NE(-1, pid);
|
||||
if (pid == 0) {
|
||||
// Instantiate an OOP exception handler.
|
||||
ExceptionHandler eh("", NULL, NULL, NULL, true, mach_port_name);
|
||||
Crasher();
|
||||
// not reached
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int ret;
|
||||
ASSERT_EQ(pid, waitpid(pid, &ret, 0));
|
||||
EXPECT_FALSE(WIFEXITED(ret));
|
||||
EXPECT_TRUE(server.Stop());
|
||||
// check that minidump was written
|
||||
ASSERT_FALSE(last_dump_name.empty());
|
||||
struct stat st;
|
||||
EXPECT_EQ(0, stat(last_dump_name.c_str(), &st));
|
||||
EXPECT_LT(0, st.st_size);
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -36,6 +36,7 @@
|
|||
#include "client/mac/handler/exception_handler.h"
|
||||
#include "client/mac/tests/auto_tempdir.h"
|
||||
|
||||
namespace {
|
||||
using std::string;
|
||||
using google_breakpad::AutoTempDir;
|
||||
using google_breakpad::ExceptionHandler;
|
||||
|
@ -76,7 +77,7 @@ TEST(ExceptionHandler, InProcess) {
|
|||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
close(fds[0]);
|
||||
ExceptionHandler eh(tempDir.path, NULL, MDCallback, &fds[1], true);
|
||||
ExceptionHandler eh(tempDir.path, NULL, MDCallback, &fds[1], true, NULL);
|
||||
// crash
|
||||
SoonToCrash();
|
||||
// not reached
|
||||
|
@ -99,3 +100,5 @@ TEST(ExceptionHandler, InProcess) {
|
|||
EXPECT_NE(0, WIFEXITED(ret));
|
||||
EXPECT_EQ(0, WEXITSTATUS(ret));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -255,11 +255,11 @@ class MachSendMessage : public MachMessage {
|
|||
class ReceivePort {
|
||||
public:
|
||||
// Creates a new mach port for receiving messages and registers a name for it
|
||||
ReceivePort(const char *receive_port_name);
|
||||
explicit ReceivePort(const char *receive_port_name);
|
||||
|
||||
// Given an already existing mach port, use it. We take ownership of the
|
||||
// port and deallocate it in our destructor.
|
||||
ReceivePort(mach_port_t receive_port);
|
||||
explicit ReceivePort(mach_port_t receive_port);
|
||||
|
||||
// Create a new mach port for receiving messages
|
||||
ReceivePort();
|
||||
|
@ -285,11 +285,11 @@ class ReceivePort {
|
|||
class MachPortSender {
|
||||
public:
|
||||
// get a port with send rights corresponding to a named registered service
|
||||
MachPortSender(const char *receive_port_name);
|
||||
explicit MachPortSender(const char *receive_port_name);
|
||||
|
||||
|
||||
// Given an already existing mach port, use it.
|
||||
MachPortSender(mach_port_t send_port);
|
||||
explicit MachPortSender(mach_port_t send_port);
|
||||
|
||||
kern_return_t SendMessage(MachSendMessage &message,
|
||||
mach_msg_timeout_t timeout);
|
||||
|
|
|
@ -240,8 +240,11 @@ kern_return_t ReceivePort::WaitForMessage(MachReceiveMessage *out_message,
|
|||
out_message->head.msgh_reserved = 0;
|
||||
out_message->head.msgh_id = 0;
|
||||
|
||||
mach_msg_option_t options = MACH_RCV_MSG;
|
||||
if (timeout != MACH_MSG_TIMEOUT_NONE)
|
||||
options |= MACH_RCV_TIMEOUT;
|
||||
kern_return_t result = mach_msg(&out_message->head,
|
||||
MACH_RCV_MSG | MACH_RCV_TIMEOUT,
|
||||
options,
|
||||
0,
|
||||
sizeof(MachMessage),
|
||||
port_,
|
||||
|
|
56
src/common/mac/scoped_task_suspend-inl.h
Normal file
56
src/common/mac/scoped_task_suspend-inl.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) 2010 Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Inline implementation of ScopedTaskSuspend, which suspends a Mach
|
||||
// task for the duration of its scope.
|
||||
|
||||
#ifndef GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_
|
||||
#define GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_
|
||||
|
||||
#include <mach/mach.h>
|
||||
|
||||
namespace google_breakpad {
|
||||
|
||||
class ScopedTaskSuspend {
|
||||
public:
|
||||
explicit ScopedTaskSuspend(mach_port_t target) : target_(target) {
|
||||
task_suspend(target_);
|
||||
}
|
||||
|
||||
~ScopedTaskSuspend() {
|
||||
task_resume(target_);
|
||||
}
|
||||
|
||||
private:
|
||||
mach_port_t target_;
|
||||
};
|
||||
|
||||
} // namespace google_breakpad
|
||||
|
||||
#endif // GOOGLE_BREAKPAD_COMMON_MAC_SCOPED_TASK_SUSPEND_H_
|
Loading…
Reference in a new issue