OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2013 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
| 8 #include <errno.h> |
8 #include <pthread.h> | 9 #include <pthread.h> |
9 #include <stdint.h> | 10 #include <stdint.h> |
10 #include <stdio.h> | 11 #include <stdio.h> |
11 #include <stdlib.h> | 12 #include <stdlib.h> |
12 #include <string.h> | 13 #include <string.h> |
13 #include <sys/mman.h> | 14 #include <sys/mman.h> |
| 15 #include <time.h> |
14 #include <unistd.h> | 16 #include <unistd.h> |
15 | 17 |
16 #include <algorithm> | 18 #include <algorithm> |
17 | 19 |
18 #include "breakpad/src/google_breakpad/common/minidump_format.h" | 20 #include "breakpad/src/google_breakpad/common/minidump_format.h" |
19 #include "native_client/src/include/elf_constants.h" | 21 #include "native_client/src/include/elf_constants.h" |
20 #include "native_client/src/include/nacl/nacl_exception.h" | 22 #include "native_client/src/include/nacl/nacl_exception.h" |
21 #include "native_client/src/include/nacl/nacl_minidump.h" | 23 #include "native_client/src/include/nacl/nacl_minidump.h" |
22 #include "native_client/src/untrusted/irt/irt.h" | |
23 #include "native_client/src/untrusted/minidump_generator/build_id.c" | 24 #include "native_client/src/untrusted/minidump_generator/build_id.c" |
24 | 25 |
25 | 26 |
26 extern char __executable_start[]; // Start of code segment | 27 extern char __executable_start[]; // Start of code segment |
27 extern char __etext[]; // End of code segment | 28 extern char __etext[]; // End of code segment |
28 | 29 |
29 #if defined(__GLIBC__) | 30 #if defined(__GLIBC__) |
30 // Variable defined by ld.so, used as a workaround for | 31 // Variable defined by ld.so, used as a workaround for |
31 // https://code.google.com/p/nativeclient/issues/detail?id=3431. | 32 // https://code.google.com/p/nativeclient/issues/detail?id=3431. |
32 extern void *__libc_stack_end; | 33 extern void *__libc_stack_end; |
(...skipping 25 matching lines...) Expand all Loading... |
58 class MinidumpFileWriter { | 59 class MinidumpFileWriter { |
59 char *buf_; | 60 char *buf_; |
60 uint32_t buf_size_; | 61 uint32_t buf_size_; |
61 uint32_t offset_; | 62 uint32_t offset_; |
62 | 63 |
63 public: | 64 public: |
64 MinidumpFileWriter() : buf_(NULL), buf_size_(0), offset_(0) { | 65 MinidumpFileWriter() : buf_(NULL), buf_size_(0), offset_(0) { |
65 void *mapping = mmap(NULL, kMinidumpBufferSize, PROT_READ | PROT_WRITE, | 66 void *mapping = mmap(NULL, kMinidumpBufferSize, PROT_READ | PROT_WRITE, |
66 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); | 67 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); |
67 if (mapping == MAP_FAILED) { | 68 if (mapping == MAP_FAILED) { |
68 fprintf(stderr, "minidump: Failed to preallocate memory\n"); | 69 perror("minidump: Failed to preallocate memory"); |
69 return; | 70 return; |
70 } | 71 } |
71 buf_ = (char *) mapping; | 72 buf_ = (char *) mapping; |
72 buf_size_ = kMinidumpBufferSize; | 73 buf_size_ = kMinidumpBufferSize; |
73 } | 74 } |
74 | 75 |
75 bool AllocateSpace(size_t size, char **ptr, uint32_t *position) { | 76 bool AllocateSpace(size_t size, char **ptr, uint32_t *position) { |
76 if (offset_ + size >= buf_size_) | 77 if (offset_ + size >= buf_size_) |
77 return false; | 78 return false; |
78 *position = offset_; | 79 *position = offset_; |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 g_callback_func(minidump_writer->data(), minidump_writer->size()); | 412 g_callback_func(minidump_writer->data(), minidump_writer->size()); |
412 | 413 |
413 // Flush streams to aid debugging, although since the process might | 414 // Flush streams to aid debugging, although since the process might |
414 // be in a corrupted state this might crash. | 415 // be in a corrupted state this might crash. |
415 fflush(NULL); | 416 fflush(NULL); |
416 | 417 |
417 _exit(127); | 418 _exit(127); |
418 } | 419 } |
419 | 420 |
420 void nacl_minidump_register_crash_handler(void) { | 421 void nacl_minidump_register_crash_handler(void) { |
421 struct nacl_irt_exception_handling irt_exception_handling; | 422 errno = nacl_exception_set_handler(CrashHandler); |
422 if (nacl_interface_query(NACL_IRT_EXCEPTION_HANDLING_v0_1, | 423 if (errno != 0) { |
423 &irt_exception_handling, | 424 perror("minidump: Failed to register an exception handler"); |
424 sizeof(irt_exception_handling)) | |
425 != sizeof(irt_exception_handling)) { | |
426 fprintf(stderr, "minidump: Exception handling IRT interface not present\n"); | |
427 return; | |
428 } | |
429 if (irt_exception_handling.exception_handler(CrashHandler, NULL) != 0) { | |
430 fprintf(stderr, "minidump: Failed to register an exception handler\n"); | |
431 return; | 425 return; |
432 } | 426 } |
433 | 427 |
434 if (!g_module_build_id_set) { | 428 if (!g_module_build_id_set) { |
435 // Try to use the nexe's built-in build ID. | 429 // Try to use the nexe's built-in build ID. |
436 const char *data_ptr; | 430 const char *data_ptr; |
437 size_t size; | 431 size_t size; |
438 if (nacl_get_build_id(&data_ptr, &size)) { | 432 if (nacl_get_build_id(&data_ptr, &size)) { |
439 // Truncate the ID if necessary. The minidump format uses a 16 | 433 // Truncate the ID if necessary. The minidump format uses a 16 |
440 // byte ID, whereas ELF build IDs are typically 20-byte SHA1 | 434 // byte ID, whereas ELF build IDs are typically 20-byte SHA1 |
(...skipping 14 matching lines...) Expand all Loading... |
455 void nacl_minidump_set_module_name(const char *module_name) { | 449 void nacl_minidump_set_module_name(const char *module_name) { |
456 g_module_name = module_name; | 450 g_module_name = module_name; |
457 } | 451 } |
458 | 452 |
459 void nacl_minidump_set_module_build_id( | 453 void nacl_minidump_set_module_build_id( |
460 const uint8_t data[NACL_MINIDUMP_BUILD_ID_SIZE]) { | 454 const uint8_t data[NACL_MINIDUMP_BUILD_ID_SIZE]) { |
461 assert(sizeof(g_module_build_id) == NACL_MINIDUMP_BUILD_ID_SIZE); | 455 assert(sizeof(g_module_build_id) == NACL_MINIDUMP_BUILD_ID_SIZE); |
462 memcpy(&g_module_build_id, data, NACL_MINIDUMP_BUILD_ID_SIZE); | 456 memcpy(&g_module_build_id, data, NACL_MINIDUMP_BUILD_ID_SIZE); |
463 g_module_build_id_set = 1; | 457 g_module_build_id_set = 1; |
464 } | 458 } |
OLD | NEW |