Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: src/client/minidump_file_writer.cc

Issue 1407233016: Android: Workaround for ftruncate() issues. (Closed) Base URL: https://chromium.googlesource.com/breakpad/breakpad@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006, Google Inc. 1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 26 matching lines...) Expand all
37 #include <string.h> 37 #include <string.h>
38 #include <unistd.h> 38 #include <unistd.h>
39 39
40 #include "client/minidump_file_writer-inl.h" 40 #include "client/minidump_file_writer-inl.h"
41 #include "common/linux/linux_libc_support.h" 41 #include "common/linux/linux_libc_support.h"
42 #include "common/string_conversion.h" 42 #include "common/string_conversion.h"
43 #if defined(__linux__) && __linux__ 43 #if defined(__linux__) && __linux__
44 #include "third_party/lss/linux_syscall_support.h" 44 #include "third_party/lss/linux_syscall_support.h"
45 #endif 45 #endif
46 46
47 #if defined(__ANDROID__)
48 #include <errno.h>
49
50 namespace {
51
52 bool g_need_ftruncate_workaround = false;
53 bool g_checked_need_ftruncate_workaround = false;
54
55 void CheckNeedsFTruncateWorkAround(int file) {
56 if (g_checked_need_ftruncate_workaround) {
57 return;
58 }
59 g_checked_need_ftruncate_workaround = true;
60
61 // Attempt an idempotent truncate that chops off nothing and see if we
62 // run into any sort of errors.
63 off_t offset = sys_lseek(file, 0, SEEK_END);
64 if (offset == -1) {
65 // lseek failed. Don't apply work around. It's unlikely that we can write
66 // to a minidump with either method.
67 return;
68 }
69
70 int result = ftruncate(file, offset);
71 if (result == -1 && errno == EACCES) {
72 // It very likely that we are running into the kernel bug in M devices.
73 // We are going to deploy the workaround for writing minidump files
74 // without uses of ftruncate(). This workaround should be fine even
75 // for kernels without the bug.
76 // See http://crbug.com/542840 for more details.
77 g_need_ftruncate_workaround = true;
78 }
79 }
80
81 bool NeedsFTruncateWorkAround() {
82 return g_need_ftruncate_workaround;
83 }
84
85 } // namespace
86 #endif // defined(__ANDROID__)
87
47 namespace google_breakpad { 88 namespace google_breakpad {
48 89
49 const MDRVA MinidumpFileWriter::kInvalidMDRVA = static_cast<MDRVA>(-1); 90 const MDRVA MinidumpFileWriter::kInvalidMDRVA = static_cast<MDRVA>(-1);
50 91
51 MinidumpFileWriter::MinidumpFileWriter() 92 MinidumpFileWriter::MinidumpFileWriter()
52 : file_(-1), 93 : file_(-1),
53 close_file_when_destroyed_(true), 94 close_file_when_destroyed_(true),
54 position_(0), 95 position_(0),
55 size_(0) { 96 size_(0) {
56 } 97 }
(...skipping 11 matching lines...) Expand all
68 file_ = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600); 109 file_ = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
69 #endif 110 #endif
70 111
71 return file_ != -1; 112 return file_ != -1;
72 } 113 }
73 114
74 void MinidumpFileWriter::SetFile(const int file) { 115 void MinidumpFileWriter::SetFile(const int file) {
75 assert(file_ == -1); 116 assert(file_ == -1);
76 file_ = file; 117 file_ = file;
77 close_file_when_destroyed_ = false; 118 close_file_when_destroyed_ = false;
119 #if defined(__ANDROID__)
120 CheckNeedsFTruncateWorkAround(file);
121 #endif
78 } 122 }
79 123
80 bool MinidumpFileWriter::Close() { 124 bool MinidumpFileWriter::Close() {
81 bool result = true; 125 bool result = true;
82 126
83 if (file_ != -1) { 127 if (file_ != -1) {
84 if (-1 == ftruncate(file_, position_)) { 128 #if defined(__ANDROID__)
129 if (!NeedsFTruncateWorkAround() && ftruncate(file_, position_)) {
85 return false; 130 return false;
86 } 131 }
132 #else
133 if (ftruncate(file_, position_)) {
134 return false;
135 }
136 #endif
87 #if defined(__linux__) && __linux__ 137 #if defined(__linux__) && __linux__
88 result = (sys_close(file_) == 0); 138 result = (sys_close(file_) == 0);
89 #else 139 #else
90 result = (close(file_) == 0); 140 result = (close(file_) == 0);
91 #endif 141 #endif
92 file_ = -1; 142 file_ = -1;
93 } 143 }
94 144
95 return result; 145 return result;
96 } 146 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 263
214 output->start_of_memory_range = reinterpret_cast<uint64_t>(src); 264 output->start_of_memory_range = reinterpret_cast<uint64_t>(src);
215 output->memory = mem.location(); 265 output->memory = mem.location();
216 266
217 return true; 267 return true;
218 } 268 }
219 269
220 MDRVA MinidumpFileWriter::Allocate(size_t size) { 270 MDRVA MinidumpFileWriter::Allocate(size_t size) {
221 assert(size); 271 assert(size);
222 assert(file_ != -1); 272 assert(file_ != -1);
273 #if defined(__ANDROID__)
274 if (NeedsFTruncateWorkAround()) {
275 // If ftruncate() is not available. We simply increase the size beyond the
276 // current file size. sys_write() will expand the file when data is written
277 // to it. Because we did not over allocate to fit memory pages, we also
278 // do not need to ftruncate() the file once we are done.
279 size_ += size;
280
281 // We don't need to seek since the file is unchanged.
282 MDRVA current_position = position_;
283 position_ += static_cast<MDRVA>(size);
284 return current_position;
285 }
286 #endif
223 size_t aligned_size = (size + 7) & ~7; // 64-bit alignment 287 size_t aligned_size = (size + 7) & ~7; // 64-bit alignment
224 288
225 if (position_ + aligned_size > size_) { 289 if (position_ + aligned_size > size_) {
226 size_t growth = aligned_size; 290 size_t growth = aligned_size;
227 size_t minimal_growth = getpagesize(); 291 size_t minimal_growth = getpagesize();
228 292
229 // Ensure that the file grows by at least the size of a memory page 293 // Ensure that the file grows by at least the size of a memory page
230 if (growth < minimal_growth) 294 if (growth < minimal_growth)
231 growth = minimal_growth; 295 growth = minimal_growth;
232 296
(...skipping 16 matching lines...) Expand all
249 assert(file_ != -1); 313 assert(file_ != -1);
250 314
251 // Ensure that the data will fit in the allocated space 315 // Ensure that the data will fit in the allocated space
252 if (static_cast<size_t>(size + position) > size_) 316 if (static_cast<size_t>(size + position) > size_)
253 return false; 317 return false;
254 318
255 // Seek and write the data 319 // Seek and write the data
256 #if defined(__linux__) && __linux__ 320 #if defined(__linux__) && __linux__
257 if (sys_lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) { 321 if (sys_lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) {
258 if (sys_write(file_, src, size) == size) { 322 if (sys_write(file_, src, size) == size) {
323 return true;
324 }
325 }
259 #else 326 #else
260 if (lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) { 327 if (lseek(file_, position, SEEK_SET) == static_cast<off_t>(position)) {
261 if (write(file_, src, size) == size) { 328 if (write(file_, src, size) == size) {
262 #endif
263 return true; 329 return true;
264 } 330 }
265 } 331 }
266 332 #endif
267 return false; 333 return false;
268 } 334 }
269 335
270 bool UntypedMDRVA::Allocate(size_t size) { 336 bool UntypedMDRVA::Allocate(size_t size) {
271 assert(size_ == 0); 337 assert(size_ == 0);
272 size_ = size; 338 size_ = size;
273 position_ = writer_->Allocate(size_); 339 position_ = writer_->Allocate(size_);
274 return position_ != MinidumpFileWriter::kInvalidMDRVA; 340 return position_ != MinidumpFileWriter::kInvalidMDRVA;
275 } 341 }
276 342
277 bool UntypedMDRVA::Copy(MDRVA pos, const void *src, size_t size) { 343 bool UntypedMDRVA::Copy(MDRVA pos, const void *src, size_t size) {
278 assert(src); 344 assert(src);
279 assert(size); 345 assert(size);
280 assert(pos + size <= position_ + size_); 346 assert(pos + size <= position_ + size_);
281 return writer_->Copy(pos, src, size); 347 return writer_->Copy(pos, src, size);
282 } 348 }
283 349
284 } // namespace google_breakpad 350 } // namespace google_breakpad
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698