File: crashpad_ios.mm

package info (click to toggle)
chromium 139.0.7258.138-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 6,120,676 kB
  • sloc: cpp: 35,100,869; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (184 lines) | stat: -rw-r--r-- 6,707 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/crash/core/app/crashpad.h"

#include <vector>

#include "base/apple/bridging.h"
#include "base/apple/bundle_locations.h"
#include "base/apple/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "build/branding_buildflags.h"
#include "components/crash/core/app/crash_reporter_client.h"
#include "third_party/crashpad/crashpad/client/crash_report_database.h"
#include "third_party/crashpad/crashpad/client/crashpad_client.h"
#include "third_party/crashpad/crashpad/client/settings.h"
#include "third_party/crashpad/crashpad/minidump/minidump_crashpad_info_writer.h"
#include "third_party/crashpad/crashpad/minidump/minidump_file_writer.h"
#include "third_party/crashpad/crashpad/minidump/minidump_simple_string_dictionary_writer.h"
#include "third_party/crashpad/crashpad/util/misc/metrics.h"

namespace crash_reporter {

namespace {

const std::map<std::string, std::string>& GetProcessSimpleAnnotations() {
  static std::map<std::string, std::string> annotations = []() -> auto {
    std::map<std::string, std::string> process_annotations;
    @autoreleasepool {
      NSBundle* outer_bundle = base::apple::OuterBundle();
#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
      process_annotations["prod"] = "Chrome_iOS";
#else
      NSString* product = base::apple::ObjCCast<NSString>(
          [outer_bundle objectForInfoDictionaryKey:base::apple::CFToNSPtrCast(
                                                       kCFBundleNameKey)]);
      process_annotations["prod"] =
          base::SysNSStringToUTF8(product).append("_iOS");
#endif

#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
      // Empty means stable.
      const bool allow_empty_channel = true;
#else
      const bool allow_empty_channel = false;
#endif
      NSString* channel = base::apple::ObjCCast<NSString>(
          [outer_bundle objectForInfoDictionaryKey:@"KSChannelID"]);
      // Must be a developer build.
      if (!allow_empty_channel && (!channel || !channel.length))
        channel = @"developer";
      process_annotations["channel"] = base::SysNSStringToUTF8(channel);
      NSString* version =
          base::apple::ObjCCast<NSString>([base::apple::FrameworkBundle()
              objectForInfoDictionaryKey:@"CFBundleVersion"]);
      process_annotations["ver"] = base::SysNSStringToUTF8(version);
      process_annotations["plat"] = std::string("iOS");
      process_annotations["crashpad"] = std::string("yes");
    }  // @autoreleasepool
    return process_annotations;
  }
  ();
  return annotations;
}

}  // namespace

void ProcessIntermediateDumps(
    const std::map<std::string, std::string>& annotations,
    const crashpad::UserStreamDataSources* user_stream_sources) {
  GetCrashpadClient().ProcessIntermediateDumps(annotations,
                                               user_stream_sources);
}

void ProcessIntermediateDump(
    const base::FilePath& file,
    const std::map<std::string, std::string>& annotations) {
  GetCrashpadClient().ProcessIntermediateDump(file, annotations);
}

bool ProcessExternalDump(
    const std::string& source,
    base::span<const uint8_t> data,
    const std::map<std::string, std::string>& override_annotations) {
  auto crashpad_info_stream =
      std::make_unique<crashpad::MinidumpCrashpadInfoWriter>();

  auto simple_string_dictionary_writer =
      std::make_unique<crashpad::MinidumpSimpleStringDictionaryWriter>();

  std::map<std::string, std::string> annotations =
      GetProcessSimpleAnnotations();
  annotations["prod"] = annotations["prod"] + "_" + source;

  for (auto& entry : override_annotations) {
    annotations[entry.first] = entry.second;
  }

  for (auto& entry : annotations) {
    auto writer =
        std::make_unique<crashpad::MinidumpSimpleStringDictionaryEntryWriter>();
    writer->SetKeyValue(entry.first, entry.second);
    simple_string_dictionary_writer->AddEntry(std::move(writer));
  }

  crashpad_info_stream->SetSimpleAnnotations(
      std::move(simple_string_dictionary_writer));

  crashpad::CrashReportDatabase* database = internal::GetCrashReportDatabase();
  if (!database) {
    return false;
  }
  std::unique_ptr<crashpad::CrashReportDatabase::NewReport> new_report;
  crashpad::CrashReportDatabase::OperationStatus database_status =
      database->PrepareNewCrashReport(&new_report);
  if (database_status != crashpad::CrashReportDatabase::kNoError) {
    return false;
  }

  crashpad::MinidumpFileWriter minidump;

  crashpad_info_stream->SetReportID(new_report->ReportID());
  crashpad::Settings* const settings = database->GetSettings();
  crashpad::UUID client_id;
  if (settings && settings->GetClientID(&client_id)) {
    crashpad_info_stream->SetClientID(client_id);
  }

  bool add_stream_result = minidump.AddStream(std::move(crashpad_info_stream));
  DCHECK(add_stream_result);

  if (data.size() > 0) {
    crashpad::FileWriter* attachment_writer = new_report->AddAttachment(source);
    attachment_writer->Write(data.data(), data.size());
  }

  if (!minidump.WriteEverything(new_report->Writer())) {
    return false;
  }

  crashpad::UUID uuid;
  database_status =
      database->FinishedWritingCrashReport(std::move(new_report), &uuid);
  if (database_status != crashpad::CrashReportDatabase::kNoError) {
    return false;
  }
  return true;
}

void StartProcessingPendingReports() {
  GetCrashpadClient().StartProcessingPendingReports();
}

namespace internal {

bool PlatformCrashpadInitialization(
    bool initial_client,
    bool browser_process,
    bool embedded_handler,
    const std::string& user_data_dir,
    const base::FilePath& exe_path,
    const std::vector<std::string>& initial_arguments,
    base::FilePath* database_path) {
  DCHECK(!embedded_handler);     // This is not used on iOS.
  DCHECK(exe_path.empty());      // This is not used on iOS.
  DCHECK(initial_arguments.empty());
  DCHECK(initial_client);

  @autoreleasepool {
    CrashReporterClient* crash_reporter_client = GetCrashReporterClient();
    crash_reporter_client->GetCrashDumpLocation(database_path);
    // Don't pass `url` to extensions since they never upload minidumps.
    std::string url = [NSBundle.mainBundle.bundlePath hasSuffix:@"appex"]
                          ? ""
                          : crash_reporter_client->GetUploadUrl();
    return GetCrashpadClient().StartCrashpadInProcessHandler(
        *database_path, url, GetProcessSimpleAnnotations(),
        crashpad::CrashpadClient::ProcessPendingReportsObservationCallback());
  }  // @autoreleasepool
}

}  // namespace internal
}  // namespace crash_reporter