30#include "llvm/ADT/StringRef.h"
31#include "llvm/BinaryFormat/Minidump.h"
32#include "llvm/Support/ConvertUTF.h"
33#include "llvm/Support/Endian.h"
34#include "llvm/Support/Error.h"
35#include "llvm/TargetParser/Triple.h"
50using namespace llvm::minidump;
63 llvm::Triple::OSType::Linux)
67 std::vector<lldb::ThreadSP> threads =
69 for (
const ThreadSP &thread_sp : threads) {
70 StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
72 const StopReason &stop_reason = stop_info_sp->GetStopReason();
90 "Failed to fill in header and directory "
91 "sections. Written / Expected (%" PRIx64
" / %" PRIx64
")",
101 uint64_t stream_size) {
106 "Unable to add directory for stream type "
107 "%x, offset is greater then 32 bit limit.",
114 "Unable to add directory for stream type %x, exceeded expected number "
115 "of directories %zu.",
120 LocationDescriptor loc;
121 loc.DataSize =
static_cast<llvm::support::ulittle32_t
>(stream_size);
126 dir.Type =
static_cast<llvm::support::little_t<StreamType>
>(type);
135 StreamType type = StreamType::LLDBGenerated;
141 const llvm::Triple &target_triple =
142 m_process_sp->GetTarget().GetArchitecture().GetTriple();
144 AddDirectory(StreamType::SystemInfo,
sizeof(llvm::minidump::SystemInfo));
148 llvm::minidump::ProcessorArchitecture arch;
149 switch (target_triple.getArch()) {
150 case llvm::Triple::ArchType::x86_64:
151 arch = ProcessorArchitecture::AMD64;
153 case llvm::Triple::ArchType::x86:
154 arch = ProcessorArchitecture::X86;
156 case llvm::Triple::ArchType::arm:
157 arch = ProcessorArchitecture::ARM;
159 case llvm::Triple::ArchType::aarch64:
160 arch = ProcessorArchitecture::ARM64;
162 case llvm::Triple::ArchType::mips64:
163 case llvm::Triple::ArchType::mips64el:
164 case llvm::Triple::ArchType::mips:
165 case llvm::Triple::ArchType::mipsel:
166 arch = ProcessorArchitecture::MIPS;
168 case llvm::Triple::ArchType::ppc64:
169 case llvm::Triple::ArchType::ppc:
170 case llvm::Triple::ArchType::ppc64le:
171 arch = ProcessorArchitecture::PPC;
175 "Architecture %s not supported.",
176 target_triple.getArchName().str().c_str());
180 llvm::support::little_t<OSPlatform> platform_id;
181 switch (target_triple.getOS()) {
182 case llvm::Triple::OSType::Linux:
183 if (target_triple.getEnvironment() ==
184 llvm::Triple::EnvironmentType::Android)
185 platform_id = OSPlatform::Android;
187 platform_id = OSPlatform::Linux;
189 case llvm::Triple::OSType::Win32:
190 platform_id = OSPlatform::Win32NT;
192 case llvm::Triple::OSType::MacOSX:
193 platform_id = OSPlatform::MacOSX;
195 case llvm::Triple::OSType::IOS:
196 platform_id = OSPlatform::IOS;
200 "OS %s not supported.", target_triple.getOSName().str().c_str());
204 llvm::minidump::SystemInfo sys_info{};
205 sys_info.ProcessorArch =
206 static_cast<llvm::support::little_t<ProcessorArchitecture>
>(arch);
208 sys_info.CSDVersionRVA =
static_cast<llvm::support::ulittle32_t
>(
210 sys_info.PlatformId = platform_id;
211 m_data.AppendData(&sys_info,
sizeof(llvm::minidump::SystemInfo));
213 std::string csd_string;
229 llvm::StringRef to_write_ref(to_write.c_str(), to_write.size() + 1);
230 llvm::SmallVector<llvm::UTF16, 128> to_write_utf16;
232 bool converted = convertUTF8ToUTF16String(to_write_ref, to_write_utf16);
235 "Unable to convert the string to UTF16. Failed to convert %s",
242 llvm::support::ulittle32_t to_write_size(to_write_utf16.size_in_bytes() - 2);
244 buffer->
AppendData(&to_write_size,
sizeof(llvm::support::ulittle32_t));
245 buffer->
AppendData(to_write_utf16.data(), to_write_utf16.size_in_bytes());
253 uint64_t SizeOfImage = 0;
255 for (
const auto §ion : *mod->GetObjectFile()->GetSectionList()) {
256 SizeOfImage += section->GetByteSize();
260 SectionSP sect_sp = mod->GetObjectFile()->GetBaseAddress().GetSection();
263 return llvm::createStringError(std::errc::operation_not_supported,
264 "Couldn't obtain the section information.");
266 lldb::addr_t sect_addr = sect_sp->GetLoadBaseAddress(&target);
273 mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target) -
275 SizeOfImage = sect_size - base_sect_offset;
280 while (next_sect_sp &&
281 next_sect_sp->GetLoadBaseAddress(&target) == next_sect_addr) {
282 sect_size = sect_sp->GetByteSize();
283 SizeOfImage += sect_size;
284 next_sect_addr += sect_size;
298 constexpr size_t minidump_module_size =
sizeof(llvm::minidump::Module);
303 llvm::support::ulittle32_t modules_count =
304 static_cast<llvm::support::ulittle32_t
>(modules.
GetSize());
317 std::vector<std::pair<ModuleSP, uint64_t>> valid_modules;
319 for (
size_t i = 0; i < modules_count; ++i) {
321 std::string module_name = mod->GetSpecificationDescription();
323 if (!maybe_mod_size) {
324 llvm::Error mod_size_err = maybe_mod_size.takeError();
326 llvm::handleAllErrors(
327 std::move(mod_size_err), [&](
const llvm::ErrorInfoBase &E) {
329 LLDB_LOGF(log,
"Unable to get the size of module %s: %s",
330 module_name.c_str(), E.message().c_str());
335 valid_modules.emplace_back(mod, *maybe_mod_size);
338 size_t module_stream_size =
sizeof(llvm::support::ulittle32_t) +
339 valid_modules.size() * minidump_module_size;
346 llvm::support::ulittle32_t count =
347 static_cast<llvm::support::ulittle32_t
>(valid_modules.size());
348 m_data.AppendData(&count,
sizeof(llvm::support::ulittle32_t));
350 for (
const auto &valid_module : valid_modules) {
352 uint64_t module_size = valid_module.second;
353 std::string module_name = mod->GetSpecificationDescription();
355 llvm::support::ulittle32_t signature =
356 static_cast<llvm::support::ulittle32_t
>(
358 auto uuid = mod->GetUUID().GetBytes();
360 VSFixedFileInfo info;
361 info.Signature =
static_cast<llvm::support::ulittle32_t
>(0u);
362 info.StructVersion =
static_cast<llvm::support::ulittle32_t
>(0u);
363 info.FileVersionHigh =
static_cast<llvm::support::ulittle32_t
>(0u);
364 info.FileVersionLow =
static_cast<llvm::support::ulittle32_t
>(0u);
365 info.ProductVersionHigh =
static_cast<llvm::support::ulittle32_t
>(0u);
366 info.ProductVersionLow =
static_cast<llvm::support::ulittle32_t
>(0u);
367 info.FileFlagsMask =
static_cast<llvm::support::ulittle32_t
>(0u);
368 info.FileFlags =
static_cast<llvm::support::ulittle32_t
>(0u);
369 info.FileOS =
static_cast<llvm::support::ulittle32_t
>(0u);
370 info.FileType =
static_cast<llvm::support::ulittle32_t
>(0u);
371 info.FileSubtype =
static_cast<llvm::support::ulittle32_t
>(0u);
372 info.FileDateHigh =
static_cast<llvm::support::ulittle32_t
>(0u);
373 info.FileDateLow =
static_cast<llvm::support::ulittle32_t
>(0u);
375 LocationDescriptor ld;
376 ld.DataSize =
static_cast<llvm::support::ulittle32_t
>(0u);
377 ld.RVA =
static_cast<llvm::support::ulittle32_t
>(0u);
381 LocationDescriptor ld_cv;
382 ld_cv.DataSize =
static_cast<llvm::support::ulittle32_t
>(
383 sizeof(llvm::support::ulittle32_t) + uuid.size());
384 ld_cv.RVA =
static_cast<llvm::support::ulittle32_t
>(
385 size_before + module_stream_size + helper_data.
GetByteSize());
387 helper_data.
AppendData(&signature,
sizeof(llvm::support::ulittle32_t));
388 helper_data.
AppendData(uuid.begin(), uuid.size());
390 llvm::minidump::Module m{};
391 m.BaseOfImage =
static_cast<llvm::support::ulittle64_t
>(
392 mod->GetObjectFile()->GetBaseAddress().GetLoadAddress(&target));
393 m.SizeOfImage =
static_cast<llvm::support::ulittle32_t
>(module_size);
394 m.Checksum =
static_cast<llvm::support::ulittle32_t
>(0);
396 static_cast<llvm::support::ulittle32_t
>(std::time(
nullptr));
397 m.ModuleNameRVA =
static_cast<llvm::support::ulittle32_t
>(
398 size_before + module_stream_size + helper_data.
GetByteSize());
399 m.VersionInfo = info;
408 m_data.AppendData(&m,
sizeof(llvm::minidump::Module));
416 llvm::StringRef reg_name) {
421 bool success = reg_ctx->
ReadRegister(reg_info, reg_value);
428 llvm::StringRef reg_name) {
433 bool success = reg_ctx->
ReadRegister(reg_info, reg_value);
440 llvm::StringRef reg_name) {
445 bool success = reg_ctx->
ReadRegister(reg_info, reg_value);
452 llvm::StringRef reg_name) {
453 return static_cast<llvm::support::ulittle16_t
>(
458 llvm::StringRef reg_name) {
459 return static_cast<llvm::support::ulittle32_t
>(
464 llvm::StringRef reg_name) {
465 return static_cast<llvm::support::ulittle64_t
>(
478 if (bytes_copied == 16)
523 return thread_context;
534 for (uint32_t i = 0; i < 31; ++i) {
535 snprintf(reg_name,
sizeof(reg_name),
"x%u", i);
545 for (uint32_t i = 0; i < 32; ++i) {
546 snprintf(reg_name,
sizeof(reg_name),
"v%u", i);
549 return thread_context;
564 case llvm::Triple::ArchType::x86_64:
567 case llvm::Triple::ArchType::aarch64:
580 case llvm::Triple::ArchType::x86_64:
582 case llvm::Triple::ArchType::aarch64:
583 return sizeof(
arm64);
599 const llvm::minidump::Thread &thread = pair.second;
600 size_t bytes_to_write =
sizeof(llvm::minidump::Thread);
601 size_t bytes_written = bytes_to_write;
603 if (
error.Fail() || bytes_to_write != bytes_written) {
605 "Wrote incorrect number of bytes to minidump file. (written %zd/%zd)",
606 bytes_written, bytes_to_write);
615 constexpr size_t minidump_thread_size =
sizeof(llvm::minidump::Thread);
616 std::vector<ThreadSP> thread_list =
621 size_t thread_stream_size =
sizeof(llvm::support::ulittle32_t) +
622 thread_list.size() * minidump_thread_size;
630 llvm::support::ulittle32_t thread_count =
631 static_cast<llvm::support::ulittle32_t
>(thread_list.size());
632 m_data.AppendData(&thread_count,
sizeof(llvm::support::ulittle32_t));
639 for (
const ThreadSP &thread_sp : thread_list) {
652 "architecture %s not supported.",
653 arch.
GetTriple().getArchName().str().c_str());
657 uint64_t
sp = reg_ctx->
GetSP();
662 MemoryDescriptor stack;
663 LocationDescriptor empty_label;
664 empty_label.DataSize = 0;
666 stack.Memory = empty_label;
667 stack.StartOfMemoryRange = 0;
668 LocationDescriptor thread_context_memory_locator;
669 thread_context_memory_locator.DataSize =
670 static_cast<llvm::support::ulittle32_t
>(thread_context.
size());
671 thread_context_memory_locator.RVA =
static_cast<llvm::support::ulittle32_t
>(
672 size_before + thread_stream_size + helper_data.
GetByteSize());
676 LLDB_LOGF(log,
"AddThreadList for thread %d: thread_context %zu bytes",
677 thread_sp->GetIndexID(), thread_context.
size());
680 llvm::minidump::Thread t;
681 t.ThreadId =
static_cast<llvm::support::ulittle32_t
>(thread_sp->GetID());
682 t.SuspendCount =
static_cast<llvm::support::ulittle32_t
>(
684 t.PriorityClass =
static_cast<llvm::support::ulittle32_t
>(0);
685 t.Priority =
static_cast<llvm::support::ulittle32_t
>(0);
686 t.EnvironmentBlock =
static_cast<llvm::support::ulittle64_t
>(0);
687 t.Stack = stack, t.Context = thread_context_memory_locator;
691 m_data.AppendData(&t,
sizeof(llvm::minidump::Thread));
694 LLDB_LOGF(log,
"AddThreadList(): total helper_data %" PRIx64
" bytes",
701 std::vector<ThreadSP> thread_list =
704 for (
const ThreadSP &thread_sp : thread_list) {
705 StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
711 constexpr size_t minidump_exception_size =
712 sizeof(llvm::minidump::ExceptionStream);
719 exp_record.ExceptionCode =
720 static_cast<llvm::support::ulittle32_t
>(stop_info_sp->GetValue());
721 exp_record.ExceptionFlags =
722 static_cast<llvm::support::ulittle32_t
>(Exception::LLDB_FLAG);
723 exp_record.ExceptionRecord =
static_cast<llvm::support::ulittle64_t
>(0);
724 exp_record.ExceptionAddress = reg_ctx_sp->GetPC();
725 exp_record.NumberParameters =
static_cast<llvm::support::ulittle32_t
>(1);
726 std::string description = stop_info_sp->GetDescription();
729 memcpy(&exp_record.ExceptionInformation, description.c_str(),
730 std::min(description.size(), Exception::MaxParameterBytes));
731 exp_record.UnusedAlignment =
static_cast<llvm::support::ulittle32_t
>(0);
732 ExceptionStream exp_stream;
733 exp_stream.ThreadId =
734 static_cast<llvm::support::ulittle32_t
>(thread_sp->GetID());
735 exp_stream.UnusedAlignment =
static_cast<llvm::support::ulittle32_t
>(0);
736 exp_stream.ExceptionRecord = exp_record;
739 exp_stream.ThreadContext = Iter->second;
741 exp_stream.ThreadContext.DataSize = 0;
742 exp_stream.ThreadContext.RVA = 0;
744 m_data.AppendData(&exp_stream, minidump_exception_size);
758 misc_info.
size =
static_cast<llvm::support::ulittle32_t
>(
762 misc_info.
flags1 =
static_cast<llvm::support::ulittle32_t
>(0);
769 static_cast<llvm::support::ulittle32_t
>(
static_cast<uint32_t
>(
772 static_cast<llvm::support::ulittle32_t
>(process_info.
GetProcessID());
775 m_data.AppendData(&misc_info,
780std::unique_ptr<llvm::MemoryBuffer>
782 auto maybe_stream = llvm::MemoryBuffer::getFileAsStream(path);
785 return std::move(maybe_stream.get());
791 if (
m_process_sp->GetTarget().GetArchitecture().GetTriple().getOS() !=
795 std::vector<std::pair<StreamType, std::string>> files_with_stream_types = {
796 {StreamType::LinuxCPUInfo,
"/proc/cpuinfo"},
797 {StreamType::LinuxLSBRelease,
"/etc/lsb-release"},
804 std::string pid_str = std::to_string(pid);
805 files_with_stream_types.push_back(
806 {StreamType::LinuxProcStatus,
"/proc/" + pid_str +
"/status"});
807 files_with_stream_types.push_back(
808 {StreamType::LinuxCMDLine,
"/proc/" + pid_str +
"/cmdline"});
809 files_with_stream_types.push_back(
810 {StreamType::LinuxEnviron,
"/proc/" + pid_str +
"/environ"});
811 files_with_stream_types.push_back(
812 {StreamType::LinuxAuxv,
"/proc/" + pid_str +
"/auxv"});
813 files_with_stream_types.push_back(
814 {StreamType::LinuxMaps,
"/proc/" + pid_str +
"/maps"});
815 files_with_stream_types.push_back(
816 {StreamType::LinuxProcStat,
"/proc/" + pid_str +
"/stat"});
817 files_with_stream_types.push_back(
818 {StreamType::LinuxProcFD,
"/proc/" + pid_str +
"/fd"});
821 for (
const auto &entry : files_with_stream_types) {
822 StreamType stream = entry.first;
823 std::string path = entry.second;
827 size_t size = memory_buffer->getBufferSize();
833 m_data.AppendData(memory_buffer->getBufferStart(), size);
847 std::vector<CoreFileMemoryRange> ranges_32;
848 llvm::Expected<CoreFileMemoryRanges> all_core_memory_ranges_maybe =
850 if (!all_core_memory_ranges_maybe)
854 *all_core_memory_ranges_maybe;
857 all_core_memory_ranges.
GetSize());
858 std::vector<CoreFileMemoryRange> all_core_memory_vec;
861 for (
const auto &core_range : all_core_memory_ranges)
862 all_core_memory_vec.push_back(core_range.data);
867 auto iterator = all_core_memory_vec.begin();
868 while (iterator != all_core_memory_vec.end()) {
871 ranges_32.push_back(*iterator);
873 iterator->range.size() +
sizeof(llvm::minidump::MemoryDescriptor);
874 iterator = all_core_memory_vec.erase(iterator);
882 total_size +=
sizeof(llvm::minidump::MemoryListHeader);
886 "Unable to write minidump. Stack memory "
887 "exceeds 32b limit. (Num Stacks %zu)",
899 if (!all_core_memory_ranges.
IsEmpty()) {
910 llvm::minidump::Header header;
911 header.Signature =
static_cast<llvm::support::ulittle32_t
>(
912 llvm::minidump::Header::MagicSignature);
913 header.Version =
static_cast<llvm::support::ulittle32_t
>(
914 llvm::minidump::Header::MagicVersion);
915 header.NumberOfStreams =
916 static_cast<llvm::support::ulittle32_t
>(
m_directories.size());
918 header.StreamDirectoryRVA =
919 static_cast<llvm::support::ulittle32_t
>(
HEADER_SIZE);
920 header.Checksum =
static_cast<llvm::support::ulittle32_t
>(
922 header.TimeDateStamp =
923 static_cast<llvm::support::ulittle32_t
>(std::time(
nullptr));
925 static_cast<llvm::support::ulittle64_t
>(0u);
928 size_t bytes_written;
936 "Unable to write the minidump header (written %zd/%zd)",
949 size_t bytes_written;
957 "unable to write the directory (written %zd/%zd)", bytes_written,
973 uint64_t total_bytes_read = 0;
978 if (
error.Fail() || bytes_read == 0) {
980 "Failed to read memory region at: 0x%" PRIx64
981 ". Bytes read: 0x%" PRIx64
", error: %s",
982 current_addr, bytes_read,
error.AsCString());
994 if (current_addr != addr + total_bytes_read) {
996 "Current addr is at unexpected address, 0x%" PRIx64
997 ", expected at 0x%" PRIx64,
998 current_addr, addr + total_bytes_read);
1003 "Unexpected address encounterd when reading memory in chunks "
1004 "0x%" PRIx64
" expected 0x%" PRIx64,
1005 current_addr, addr + total_bytes_read);
1014 addDataError =
AddData(buf, bytes_read);
1015 if (addDataError.
Fail())
1018 total_bytes_read += bytes_read;
1021 if (bytes_read != data_buffer.
GetByteSize() && total_bytes_read != size) {
1023 "Memory region at: 0x%" PRIx64
" partial read 0x%" PRIx64
1024 " bytes out of 0x%" PRIx64
" bytes.",
1025 current_addr, bytes_read,
1039 return addDataError;
1044 uint64_t max_size = 0;
1045 for (
const auto &core_range : ranges)
1046 max_size = std::max(max_size, core_range.range.size());
1053 std::vector<MemoryDescriptor> descriptors;
1055 if (ranges.size() == 0)
1059 size_t region_index = 0;
1062 for (
const auto &core_range : ranges) {
1065 const addr_t addr = core_range.range.start();
1066 const addr_t size = core_range.range.size();
1067 const addr_t end = core_range.range.end();
1070 "AddMemoryList %zu/%zu reading memory for region "
1071 "(0x%" PRIx64
" bytes) [0x%" PRIx64
", 0x%" PRIx64
")",
1072 region_index, ranges.size(), size, addr, addr + size);
1075 progress.
Increment(1,
"Adding Memory Range " + core_range.Dump());
1076 uint64_t bytes_read = 0;
1083 if (bytes_read == 0)
1086 MemoryDescriptor descriptor;
1087 descriptor.StartOfMemoryRange =
1088 static_cast<llvm::support::ulittle64_t
>(addr);
1089 descriptor.Memory.DataSize =
1090 static_cast<llvm::support::ulittle32_t
>(bytes_read);
1091 descriptor.Memory.RVA =
1092 static_cast<llvm::support::ulittle32_t
>(offset_for_data);
1093 descriptors.push_back(descriptor);
1102 sizeof(llvm::minidump::MemoryListHeader) +
1103 descriptors.size() *
1104 sizeof(llvm::minidump::MemoryDescriptor));
1108 llvm::minidump::MemoryListHeader list_header;
1109 llvm::support::ulittle32_t memory_ranges_num =
1110 static_cast<llvm::support::ulittle32_t
>(descriptors.size());
1111 list_header.NumberOfMemoryRanges = memory_ranges_num;
1112 m_data.AppendData(&list_header,
sizeof(llvm::minidump::MemoryListHeader));
1115 m_data.AppendData(descriptors.data(),
1116 descriptors.size() *
sizeof(MemoryDescriptor));
1129 (
sizeof(llvm::minidump::Memory64ListHeader)) +
1131 sizeof(llvm::minidump::MemoryDescriptor_64));
1135 llvm::minidump::Memory64ListHeader list_header;
1136 llvm::support::ulittle64_t memory_ranges_num =
1137 static_cast<llvm::support::ulittle64_t
>(ranges.size());
1138 list_header.NumberOfMemoryRanges = memory_ranges_num;
1147 (ranges.size() *
sizeof(llvm::minidump::MemoryDescriptor_64));
1148 llvm::support::ulittle64_t memory_ranges_base_rva =
1149 static_cast<llvm::support::ulittle64_t
>(base_rva);
1150 list_header.BaseRVA = memory_ranges_base_rva;
1151 m_data.AppendData(&list_header,
sizeof(llvm::minidump::Memory64ListHeader));
1155 bool cleanup_required =
false;
1156 std::vector<MemoryDescriptor_64> descriptors;
1159 for (
const auto core_range : ranges) {
1161 MemoryDescriptor_64 memory_desc;
1162 memory_desc.StartOfMemoryRange =
1163 static_cast<llvm::support::ulittle64_t
>(core_range.range.start());
1164 memory_desc.DataSize =
1165 static_cast<llvm::support::ulittle64_t
>(core_range.range.size());
1166 descriptors.push_back(memory_desc);
1168 m_data.AppendData(&memory_desc,
sizeof(MemoryDescriptor_64));
1172 size_t region_index = 0;
1173 for (
const auto &core_range : ranges) {
1174 const addr_t addr = core_range.range.start();
1175 const addr_t size = core_range.range.size();
1178 "AddMemoryList_64 %zu/%zu reading memory for region "
1179 "(%" PRIx64
"bytes) "
1180 "[%" PRIx64
", %" PRIx64
")",
1181 region_index, ranges.size(), size, addr, addr + size);
1183 progress.
Increment(1,
"Adding Memory Range " + core_range.Dump());
1184 uint64_t bytes_read = 0;
1189 if (bytes_read == 0) {
1190 cleanup_required =
true;
1191 descriptors[region_index].DataSize = 0;
1193 if (bytes_read != size) {
1194 cleanup_required =
true;
1195 descriptors[region_index].DataSize = bytes_read;
1202 if (!cleanup_required) {
1209 size_t bytes_written =
sizeof(MemoryDescriptor_64) * descriptors.size();
1212 bytes_written !=
sizeof(MemoryDescriptor_64) * descriptors.size()) {
1214 "unable to write the memory descriptors (written %zd/%zd)",
1215 bytes_written,
sizeof(MemoryDescriptor_64) * descriptors.size());
1224 m_data.AppendData(data, size);
1236 addr_t remaining_bytes = starting_size;
1239 while (remaining_bytes > 0) {
1240 size_t bytes_written = remaining_bytes;
1246 "Wrote incorrect number of bytes to minidump file. (written %" PRIx64
1248 starting_size - remaining_bytes, starting_size);
1252 offset += bytes_written;
1253 remaining_bytes -= bytes_written;
1287 LLDB_LOGF(log,
"Failed to close minidump file: %s",
error.AsCString());
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
llvm::support::ulittle16_t read_register_u16(RegisterContext *reg_ctx, llvm::StringRef reg_name)
static uint64_t GetLargestRangeSize(const std::vector< CoreFileMemoryRange > &ranges)
uint64_t read_register_u64_raw(RegisterContext *reg_ctx, llvm::StringRef reg_name)
Status WriteString(const std::string &to_write, lldb_private::DataBufferHeap *buffer)
lldb_private::minidump::MinidumpContext_x86_64 GetThreadContext_x86_64(RegisterContext *reg_ctx)
llvm::Expected< uint64_t > getModuleFileSize(Target &target, const ModuleSP &mod)
uint16_t read_register_u16_raw(RegisterContext *reg_ctx, llvm::StringRef reg_name)
llvm::support::ulittle32_t read_register_u32(RegisterContext *reg_ctx, llvm::StringRef reg_name)
void read_register_u128(RegisterContext *reg_ctx, llvm::StringRef reg_name, uint8_t *dst)
std::unique_ptr< llvm::MemoryBuffer > getFileStreamHelper(const std::string &path)
llvm::support::ulittle64_t read_register_u64(RegisterContext *reg_ctx, llvm::StringRef reg_name)
minidump::RegisterContextMinidump_ARM64::Context GetThreadContext_ARM64(RegisterContext *reg_ctx)
uint32_t read_register_u32_raw(RegisterContext *reg_ctx, llvm::StringRef reg_name)
Structure holding data neccessary for minidump file creation.
lldb_private::Status WriteString(const std::string &to_write, lldb_private::DataBufferHeap *buffer)
const void * data() const
llvm::Triple::ArchType m_arch
lldb_private::minidump::MinidumpContext_x86_64 x86_64
lldb_private::minidump::RegisterContextMinidump_ARM64::Context arm64
bool prepareRegisterContext(RegisterContext *reg_ctx)
ArchThreadContexts(llvm::Triple::ArchType arch)
lldb_private::Status AddExceptions()
std::unordered_map< lldb::tid_t, llvm::minidump::LocationDescriptor > m_tid_to_reg_ctx
lldb_private::Status AddLLDBGeneratedStream()
lldb_private::Status AddThreadList()
lldb_private::Status AddHeaderAndCalculateDirectories()
uint64_t m_saved_data_size
static constexpr uint64_t MAX_WRITE_CHUNK_SIZE
static constexpr size_t DIRECTORY_SIZE
lldb_private::DataBufferHeap m_data
lldb_private::Status AddSystemInfo()
lldb_private::Status ReadWriteMemoryInChunks(lldb_private::DataBufferHeap &data_buffer, const lldb_private::CoreFileMemoryRange &range, uint64_t &bytes_read)
lldb_private::Status AddMemoryList()
std::unordered_map< lldb::addr_t, llvm::minidump::Thread > m_thread_by_range_end
lldb_private::Status AddData(const void *data, uint64_t size)
lldb_private::Status DumpFile()
lldb_private::SaveCoreOptions m_save_core_options
lldb_private::Status FlushBufferToDisk()
size_t m_expected_directories
lldb::offset_t m_thread_list_start
lldb_private::Status AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size)
lldb_private::Status FixThreadStacks()
void DeleteFile() noexcept
lldb::ProcessSP m_process_sp
static constexpr size_t HEADER_SIZE
lldb::offset_t GetCurrentDataEndOffset() const
lldb_private::Status AddMemoryList_32(std::vector< lldb_private::CoreFileMemoryRange > &ranges, lldb_private::Progress &progress)
std::vector< llvm::minidump::Directory > m_directories
lldb_private::Status DumpDirectories() const
lldb_private::Status AddLinuxFileStreams()
lldb_private::Status AddModuleList()
lldb_private::Status AddMiscInfo()
lldb_private::Status DumpHeader() const
lldb_private::Status AddMemoryList_64(std::vector< lldb_private::CoreFileMemoryRange > &ranges, lldb_private::Progress &progress)
A section + offset based address class.
lldb::SectionSP GetSection() const
Get const accessor for the section.
An architecture specification class.
llvm::Triple & GetTriple()
Architecture triple accessor.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
A subclass of DataBuffer that stores a data buffer on the heap.
lldb::offset_t GetByteSize() const override
Get the number of bytes in the data buffer.
void AppendData(const void *src, uint64_t src_len)
A collection class for Module objects.
lldb::ModuleSP GetModuleAtIndex(size_t idx) const
Get the module shared pointer for the module at index idx.
size_t GetSize() const
Gets the size of the module list.
@ eTypeJIT
JIT code that has symbols, sections and possibly debug info.
bool ProcessIDIsValid() const
lldb::pid_t GetProcessID() const
std::function< IterationAction(lldb_private::Status &error, lldb::addr_t bytes_addr, const void *bytes, lldb::offset_t bytes_size)> ReadMemoryChunkCallback
A Progress indicator helper class.
void Increment(uint64_t amount=1, std::optional< std::string > updated_detail={})
Increment the progress and send a notification to the installed callback.
uint64_t GetSP(uint64_t fail_value=LLDB_INVALID_ADDRESS)
const RegisterInfo * GetRegisterInfoByName(llvm::StringRef reg_name, uint32_t start_idx=0)
virtual bool ReadRegister(const RegisterInfo *reg_info, RegisterValue ®_value)=0
uint16_t GetAsUInt16(uint16_t fail_value=UINT16_MAX, bool *success_ptr=nullptr) const
uint32_t GetAsMemoryData(const RegisterInfo ®_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
bool Fail() const
Test for error condition.
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, uint32_t stop_id=SectionLoadHistory::eStopIDNow, bool allow_section_end=false)
const ModuleList & GetImages() const
Get accessor for the images for this process.
const ArchSpec & GetArchitecture() const
uint8_t * GetBytes()
Get a pointer to the data.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
IterationAction
Useful for callbacks whose return type indicates whether to continue iteration or short-circuit.
std::shared_ptr< lldb_private::Thread > ThreadSP
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
std::shared_ptr< lldb_private::Section > SectionSP
StopReason
Thread stop reasons.
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
std::shared_ptr< lldb_private::Module > ModuleSP
BaseType GetRangeEnd() const
Every register is described in detail including its name, alternate name (optional),...
llvm::support::ulittle16_t fs
llvm::support::ulittle64_t rdx
llvm::support::ulittle16_t cs
llvm::support::ulittle64_t rsp
llvm::support::ulittle16_t ss
llvm::support::ulittle64_t rbx
llvm::support::ulittle16_t ds
llvm::support::ulittle64_t gs_base
llvm::support::ulittle64_t r8
llvm::support::ulittle16_t gs
llvm::support::ulittle64_t rcx
llvm::support::ulittle64_t r10
llvm::support::ulittle64_t r15
llvm::support::ulittle64_t rbp
llvm::support::ulittle64_t r13
llvm::support::ulittle64_t r12
llvm::support::ulittle64_t rsi
llvm::support::ulittle64_t p1_home
llvm::support::ulittle64_t rax
llvm::support::ulittle32_t context_flags
llvm::support::ulittle64_t rdi
llvm::support::ulittle64_t r14
llvm::support::ulittle32_t eflags
llvm::support::ulittle64_t r9
llvm::support::ulittle64_t fs_base
llvm::support::ulittle64_t rip
llvm::support::ulittle64_t r11
llvm::support::ulittle32_t process_id
llvm::support::ulittle32_t flags1
llvm::support::ulittle32_t size