| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/crash/core/common/crash_key.h" |
| |
| #include <dispatch/dispatch.h> |
| |
| #include "base/strings/sys_string_conversions.h" |
| #include "components/crash/core/common/crash_key_base_support.h" |
| #import "third_party/breakpad/breakpad/src/client/ios/Breakpad.h" |
| #import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| // The iOS Breakpad implementation internally uses a LongStringDictionary, |
| // which performs the same chunking done by crash_key_breakpad.cc. This class |
| // implementation therefore just wraps the iOS Breakpad interface. |
| |
| namespace crash_reporter { |
| namespace internal { |
| |
| namespace { |
| |
| // Accessing the BreakpadRef is done on an async queue, so serialize the |
| // access to the current thread, as the CrashKeyString API is sync. This |
| // matches //ios/chrome/browser/crash_report/breakpad_helper.mm. |
| void WithBreakpadRefSync(void (^block)(BreakpadRef ref)) { |
| dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); |
| |
| [[BreakpadController sharedInstance] withBreakpadRef:^(BreakpadRef ref) { |
| block(ref); |
| dispatch_semaphore_signal(semaphore); |
| }]; |
| dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); |
| } |
| |
| } // namespace |
| |
| void CrashKeyStringImpl::Set(base::StringPiece value) { |
| NSString* key = base::SysUTF8ToNSString(name_); |
| NSString* value_ns = base::SysUTF8ToNSString(value.as_string()); |
| |
| WithBreakpadRefSync(^(BreakpadRef ref) { |
| BreakpadAddUploadParameter(ref, key, value_ns); |
| }); |
| } |
| |
| void CrashKeyStringImpl::Clear() { |
| NSString* key = base::SysUTF8ToNSString(name_); |
| |
| WithBreakpadRefSync(^(BreakpadRef ref) { |
| BreakpadRemoveUploadParameter(ref, key); |
| }); |
| } |
| |
| bool CrashKeyStringImpl::is_set() const { |
| __block bool is_set = false; |
| NSString* key = base::SysUTF8ToNSString( |
| std::string(BREAKPAD_SERVER_PARAMETER_PREFIX) + name_); |
| |
| WithBreakpadRefSync(^(BreakpadRef ref) { |
| is_set = BreakpadKeyValue(ref, key) != nil; |
| }); |
| |
| return is_set; |
| } |
| |
| } // namespace internal |
| |
| void InitializeCrashKeys() { |
| InitializeCrashKeyBaseSupport(); |
| } |
| |
| std::string GetCrashKeyValue(const std::string& key_name) { |
| __block NSString* value; |
| NSString* key = base::SysUTF8ToNSString( |
| std::string(BREAKPAD_SERVER_PARAMETER_PREFIX) + key_name); |
| |
| internal::WithBreakpadRefSync(^(BreakpadRef ref) { |
| value = BreakpadKeyValue(ref, key); |
| }); |
| |
| return base::SysNSStringToUTF8(value); |
| } |
| |
| void ResetCrashKeysForTesting() { |
| // There's no way to do this on iOS without tearing down the |
| // BreakpadController. |
| } |
| |
| } // namespace crash_reporter |