toolkit/crashreporter/google-breakpad/src/client/mac/crash_generation/ConfigFile.mm

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:21565709e7c3
1 // Copyright (c) 2011, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Utility class that can persist a SimpleStringDictionary to disk.
31
32 #import "client/mac/crash_generation/ConfigFile.h"
33
34 #import <Foundation/Foundation.h>
35 #include <stdio.h>
36 #include <sys/time.h>
37
38 #import "client/apple/Framework/BreakpadDefines.h"
39 #import "common/mac/SimpleStringDictionary.h"
40 #import "GTMDefines.h"
41
42 #define VERBOSE 0
43
44 #if VERBOSE
45 bool gDebugLog = true;
46 #else
47 bool gDebugLog = false;
48 #endif
49
50 #define DEBUGLOG if (gDebugLog) fprintf
51
52 namespace google_breakpad {
53
54 //=============================================================================
55 BOOL EnsureDirectoryPathExists(NSString *dirPath) {
56 NSFileManager *mgr = [NSFileManager defaultManager];
57
58 NSDictionary *attrs =
59 [NSDictionary dictionaryWithObject:[NSNumber numberWithUnsignedLong:0750]
60 forKey:NSFilePosixPermissions];
61
62 return [mgr createDirectoryAtPath:dirPath
63 withIntermediateDirectories:YES
64 attributes:attrs
65 error:nil];
66 }
67
68 //=============================================================================
69 BOOL ConfigFile::WriteData(const void *data, size_t length) {
70 size_t result = write(config_file_, data, length);
71
72 return result == length;
73 }
74
75 //=============================================================================
76 BOOL ConfigFile::AppendConfigData(const char *key,
77 const void *data, size_t length) {
78 assert(config_file_ != -1);
79
80 if (!key) {
81 DEBUGLOG(stderr, "Breakpad: Missing Key\n");
82 return NO;
83 }
84
85 if (!data) {
86 DEBUGLOG(stderr, "Breakpad: Missing data for key: %s\n", key ? key :
87 "<Unknown Key>");
88 return NO;
89 }
90
91 // Write the key, \n, length of data (ascii integer), \n, data
92 char buffer[16];
93 char nl = '\n';
94 BOOL result = WriteData(key, strlen(key));
95
96 snprintf(buffer, sizeof(buffer) - 1, "\n%lu\n", length);
97 result &= WriteData(buffer, strlen(buffer));
98 result &= WriteData(data, length);
99 result &= WriteData(&nl, 1);
100 return result;
101 }
102
103 //=============================================================================
104 BOOL ConfigFile::AppendConfigString(const char *key,
105 const char *value) {
106 return AppendConfigData(key, value, strlen(value));
107 }
108
109 //=============================================================================
110 BOOL ConfigFile::AppendCrashTimeParameters(const char *processStartTimeString) {
111 // Set process uptime parameter
112 struct timeval tv;
113 gettimeofday(&tv, NULL);
114
115 char processUptimeString[32], processCrashtimeString[32];
116 // Set up time if we've received the start time.
117 if (processStartTimeString) {
118 time_t processStartTime = strtol(processStartTimeString, NULL, 10);
119 time_t processUptime = tv.tv_sec - processStartTime;
120 // Store the uptime in milliseconds.
121 sprintf(processUptimeString, "%llu",
122 static_cast<unsigned long long int>(processUptime) * 1000);
123 if (!AppendConfigString(BREAKPAD_PROCESS_UP_TIME, processUptimeString))
124 return false;
125 }
126
127 sprintf(processCrashtimeString, "%zd", tv.tv_sec);
128 return AppendConfigString(BREAKPAD_PROCESS_CRASH_TIME,
129 processCrashtimeString);
130 }
131
132 //=============================================================================
133 void ConfigFile::WriteFile(const char* directory,
134 const SimpleStringDictionary *configurationParameters,
135 const char *dump_dir,
136 const char *minidump_id) {
137
138 assert(config_file_ == -1);
139
140 // Open and write out configuration file preamble
141 if (directory) {
142 snprintf(config_file_path_, sizeof(config_file_path_), "%s/Config-XXXXXX",
143 directory);
144 } else {
145 strlcpy(config_file_path_, "/tmp/Config-XXXXXX",
146 sizeof(config_file_path_));
147 }
148 config_file_ = mkstemp(config_file_path_);
149
150 if (config_file_ == -1) {
151 DEBUGLOG(stderr,
152 "mkstemp(config_file_path_) == -1 (%s)\n",
153 strerror(errno));
154 return;
155 }
156 else {
157 DEBUGLOG(stderr, "Writing config file to (%s)\n", config_file_path_);
158 }
159
160 has_created_file_ = true;
161
162 // Add the minidump dir
163 AppendConfigString(kReporterMinidumpDirectoryKey, dump_dir);
164 AppendConfigString(kReporterMinidumpIDKey, minidump_id);
165
166 // Write out the configuration parameters
167 BOOL result = YES;
168 const SimpleStringDictionary &dictionary = *configurationParameters;
169
170 const KeyValueEntry *entry = NULL;
171 SimpleStringDictionaryIterator iter(dictionary);
172
173 while ((entry = iter.Next())) {
174 DEBUGLOG(stderr,
175 "config: (%s) -> (%s)\n",
176 entry->GetKey(),
177 entry->GetValue());
178 result = AppendConfigString(entry->GetKey(), entry->GetValue());
179
180 if (!result)
181 break;
182 }
183 AppendCrashTimeParameters(
184 configurationParameters->GetValueForKey(BREAKPAD_PROCESS_START_TIME));
185
186 close(config_file_);
187 config_file_ = -1;
188 }
189
190 } // namespace google_breakpad

mercurial