| 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 |