| 76 | } |
| 77 | |
| 78 | LONG NTAPI veh(PEXCEPTION_POINTERS p) { |
| 79 | if (data.capture_stacktraces_at_throw && |
| 80 | PER_IS_MSVC_EH(p->ExceptionRecord) && |
| 81 | !is_processing_rethrow(p->ExceptionRecord)) { |
| 82 | HANDLE hHeap = GetProcessHeap(); |
| 83 | unsigned index = current_cxx_exception_index(); |
| 84 | unsigned new_count = 1 + (index < data.count ? index + 1 : 0); |
| 85 | |
| 86 | for (unsigned i = new_count; i < data.count; ++i) { |
| 87 | HeapFree(hHeap, 0, data.info[i].dump); |
| 88 | data.info[i].dump = nullptr; |
| 89 | } |
| 90 | |
| 91 | void* new_info; |
| 92 | if (data.info) { |
| 93 | new_info = HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, data.info, sizeof(thrown_info) * new_count); |
| 94 | } else { |
| 95 | new_info = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(thrown_info) * new_count); |
| 96 | } |
| 97 | if (new_info) { |
| 98 | data.count = new_count; |
| 99 | data.info = static_cast<thrown_info*>(new_info); |
| 100 | data.info[data.count - 1].object = PER_PEXCEPTOBJ(p->ExceptionRecord); |
| 101 | char*& dump_ptr = data.info[data.count - 1].dump; |
| 102 | if (dump_ptr == nullptr) { |
| 103 | dump_ptr = static_cast<char*>(HeapAlloc(hHeap, 0, kStacktraceDumpSize)); |
| 104 | } |
| 105 | if (dump_ptr != nullptr) { |
| 106 | const std::size_t kSkip = 4; |
| 107 | boost::stacktrace::safe_dump_to(kSkip, dump_ptr, kStacktraceDumpSize); |
| 108 | } |
| 109 | } else if (new_count <= data.count) { |
| 110 | data.count = new_count - 1; |
| 111 | HeapFree(hHeap, 0, data.info[data.count - 1].dump); |
| 112 | data.info[data.count - 1].dump = nullptr; |
| 113 | } |
| 114 | } |
| 115 | return EXCEPTION_CONTINUE_SEARCH; |
| 116 | } |
| 117 | |
| 118 | struct veh_installer { |
| 119 | PVOID h; |
nothing calls this directly
no test coverage detected