[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-25 Thread Jacob Lalonde via lldb-commits

Jlalond wrote:

@petrhosek I am working on this. I think it's only the header thankfully

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-25 Thread Petr Hosek via lldb-commits

petrhosek wrote:

We're seeing the same issue as well on our builders, will you be able to 
address this today?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-25 Thread Vladimir Vereschaka via lldb-commits

vvereschaka wrote:

@Jlalond , perfect, thank you. It is ok for me if you'll fix the problem during 
today.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-25 Thread Jacob Lalonde via lldb-commits

Jlalond wrote:

@vvereschaka I'll work on this today. Is it time pressing enough you would want 
everything reverted?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-24 Thread Vladimir Vereschaka via lldb-commits

vvereschaka wrote:

Hi @Jlalond ,
here is still a problem with the window builds:
```
FAILED: 
tools/lldb/source/Plugins/ObjectFile/Minidump/CMakeFiles/lldbPluginObjectFileMinidump.dir/ObjectFileMinidump.cpp.obj
 
ccache C:\PROGRA~1\LLVM\bin\clang-cl.exe  /nologo -TP -DGTEST_HAS_RTTI=0 
-DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS 
-D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS 
-D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_HAS_EXCEPTIONS=0 
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\source\Plugins\ObjectFile\Minidump
 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Plugins\ObjectFile\Minidump
 -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\include 
-IC:\Users\tcwg\AppData\Local\Programs\Python\Python311-arm64\include 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\llvm\..\clang\include
 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\..\clang\include
 -IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source 
-IC:\Users\tcwg\llvm-worker\lldb-aarch64-windows\build\tools\lldb\source 
/DWIN32 /D_WINDOWS   /Zc:inline /Zc:__cplusplus /Oi /Brepro /bigobj 
/permissive- -Werror=unguarded-availability-new /W4  -Wextra 
-Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers 
-Wimplicit-fallthrough -Wcovered-switch-default -Wno-noexcept-type 
-Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wsuggest-override 
-Wstring-conversion -Wmisleading-indentation -Wctad-maybe-unsupported /Gw 
-Wno-deprecated-register -Wno-vla-extension /O2 /Ob2 /DNDEBUG -MD   -wd4018 
-wd4068 -wd4150 -wd4201 -wd4251 -wd4521 -wd4530 -wd4589  /EHs-c- /GR- 
-std:c++17 /showIncludes 
/Fotools\lldb\source\Plugins\ObjectFile\Minidump\CMakeFiles\lldbPluginObjectFileMinidump.dir\ObjectFileMinidump.cpp.obj
 
/Fdtools\lldb\source\Plugins\ObjectFile\Minidump\CMakeFiles\lldbPluginObjectFileMinidump.dir\lldbPluginObjectFileMinidump.pdb
 -c -- 
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Plugins\ObjectFile\Minidump\ObjectFileMinidump.cpp
C:\Users\tcwg\llvm-worker\lldb-aarch64-windows\llvm-project\lldb\source\Plugins\ObjectFile\Minidump\ObjectFileMinidump.cpp(21,10):
 fatal error: 'unistd.h' file not found
   21 | #include 
  |  ^~
1 error generated.
```

* https://lab.llvm.org/buildbot/#/builders/141/builds/266
* https://lab.llvm.org/buildbot/#/builders/141/builds/250

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-24 Thread Jacob Lalonde via lldb-commits

Jlalond wrote:

Fixed uint issue in #96564

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-24 Thread Jacob Lalonde via lldb-commits

Jlalond wrote:

@petrhosek because it's just going to be a change to something like `size_t`, 
would you mind if I just did a quick commit to fix this and assign you as the 
reviewer? 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-24 Thread Petr Hosek via lldb-commits

petrhosek wrote:

This broke the Windows build with the following error:
```
C:\b\s\w\ir\x\w\cipd\bin\clang-cl.exe  /nologo -TP -DGTEST_HAS_RTTI=0 
-DLIBXML_STATIC -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE 
-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS 
-D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_GLIBCXX_ASSERTIONS -D_HAS_EXCEPTIONS=0 
-D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS 
-IC:\b\s\w\ir\x\w\llvm_build\tools\lldb\source\Plugins\ObjectFile\Minidump 
-IC:\b\s\w\ir\x\w\llvm-llvm-project\lldb\source\Plugins\ObjectFile\Minidump 
-IC:\b\s\w\ir\x\w\llvm-llvm-project\lldb\include 
-IC:\b\s\w\ir\x\w\llvm_build\tools\lldb\include 
-IC:\b\s\w\ir\x\w\rc\tensorflow-venv\store\python_venv-51qj4upsi8nrslpsnfp48k5j14\contents\Lib\site-packages\tensorflow\include
 -IC:\b\s\w\ir\x\w\llvm_build\include 
-IC:\b\s\w\ir\x\w\llvm-llvm-project\llvm\include 
-IC:\b\s\w\ir\x\w\lldb_install\python3\include 
-IC:\b\s\w\ir\x\w\llvm-llvm-project\llvm\..\clang\include 
-IC:\b\s\w\ir\x\w\llvm_build\tools\lldb\..\clang\include 
-IC:\b\s\w\ir\x\w\llvm-llvm-project\lldb\source 
-IC:\b\s\w\ir\x\w\llvm_build\tools\lldb\source 
-imsvcC:\b\s\w\ir\x\w\libxml2_install_target\include\libxml2 
-imsvcC:\b\s\w\ir\x\w\zlib_install_target\include 
-imsvcC:\b\s\w\ir\x\w\zstd_install\include /DWIN32 /D_WINDOWS   /Zc:inline 
/Zc:__cplusplus /Oi /Brepro /bigobj /permissive- 
-Werror=unguarded-availability-new /W4  -Wextra -Wno-unused-parameter 
-Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wimplicit-fallthrough 
-Wcovered-switch-default -Wno-noexcept-type -Wnon-virtual-dtor 
-Wdelete-non-virtual-dtor -Wsuggest-override -Wstring-conversion 
-Wmisleading-indentation -Wctad-maybe-unsupported /Gw -Wno-deprecated-register 
-Wno-vla-extension /O2 /Ob2  -std:c++17 -MT   -wd4018 -wd4068 -wd4150 -wd4201 
-wd4251 -wd4521 -wd4530 -wd4589  /EHs-c- /GR- -UNDEBUG /showIncludes 
/Fotools\lldb\source\Plugins\ObjectFile\Minidump\CMakeFiles\lldbPluginObjectFileMinidump.dir\MinidumpFileBuilder.cpp.obj
 
/Fdtools\lldb\source\Plugins\ObjectFile\Minidump\CMakeFiles\lldbPluginObjectFileMinidump.dir\lldbPluginObjectFileMinidump.pdb
 -c -- 
C:\b\s\w\ir\x\w\llvm-llvm-project\lldb\source\Plugins\ObjectFile\Minidump\MinidumpFileBuilder.cpp
In file included from 
C:\b\s\w\ir\x\w\llvm-llvm-project\lldb\source\Plugins\ObjectFile\Minidump\MinidumpFileBuilder.cpp:9:
C:\b\s\w\ir\x\w\llvm-llvm-project\lldb\source\Plugins\ObjectFile\Minidump\MinidumpFileBuilder.h(149,3):
 error: unknown type name 'uint'; did you mean 'int'?
  149 |   uint m_expected_directories = 0;
  |   ^~~~
  |   int
1 error generated.
```
Would it be possible to take a look and revert if necessary?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-24 Thread Greg Clayton via lldb-commits

https://github.com/clayborg closed 
https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-18 Thread Greg Clayton via lldb-commits

https://github.com/clayborg approved this pull request.

Looks good to me!

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-18 Thread Jacob Lalonde via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);

Jlalond wrote:

This actually works, because we'll never enter the loop unless 
`all_core_memory_ranges` is non empty, where total_size will actually be used. 
Prior to code review feedback we always called to get memory ranges, even when 
it's just stacks, ensuring we would always have at least stacks in 
`all_core_memory_ranges`. 

I have added the check for empty and an explanation comment as well.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t range_size = core_range.range.size();

clayborg wrote:

make `const`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);

clayborg wrote:

this `total_size` will be wrong if `all_core_memory_ranges` is empty right? If 
we are saving stacks only, this will be:
```
256 + (0 - stack_start_addresses.size()) * 
sizeof(llvm::minidump::MemoryDescriptor_64);
```
And we will unsigned underflow but it won't matter because we won't use 
`total_size`. Best to put a:
```
if (!all_core_memory_ranges.empty()) {
```
around the `total_size` and for loop that iterates over all core ranges to 
avoid potential issues in the future.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -20,25 +20,98 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size = HEADER_SIZE;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
+  // (corresponding memory list for stacks) And an additional memory list for
+  // non-stacks.
+  lldb_private::Target  = m_process_sp->GetTarget();
+  m_expected_directories = 6;
+  // Check if OS is linux and reserve directory space for all linux specific
+  // breakpad extension directories.
+  if (target.GetArchitecture().GetTriple().getOS() ==
+  llvm::Triple::OSType::Linux)
+m_expected_directories += 9;
+
+  // Go through all of the threads and check for exceptions.
+  lldb_private::ThreadList thread_list = m_process_sp->GetThreadList();
+  const uint32_t num_threads = thread_list.GetSize();
+  for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+if (stop_info_sp &&
+stop_info_sp->GetStopReason() == StopReason::eStopReasonException) {
+  m_expected_directories++;
+}
+  }
+
+  m_saved_data_size +=
+  m_expected_directories * sizeof(llvm::minidump::Directory);
+  Status error;
+  offset_t new_offset = m_core_file->SeekFromStart(m_saved_data_size);
+  if (new_offset != m_saved_data_size)
+error.SetErrorStringWithFormat("Failed to fill in header and directory "
+   "sections. Written / Expected (%" PRIx64
+   " / %zu)",

clayborg wrote:

`m_saved_data_size` is uint64_t, so don't use `" / %zu)`, use ` / %" PRIu64 ")"

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +807,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  // We first save the thread stacks to ensure they fit in the first UINT32_MAX
+  // bytes of the core file. Thread structures in minidump files can only use
+  // 32 bit memory descriptiors, so we emit them first to ensure the memory is
+  // in accessible with a 32 bit offset.
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // After saving the stacks, we start packing as much as we can into 32b.
+  // We apply a generous padding here so that the Directory, MemoryList and
+  // Memory64List sections all begin in 32b addressable space.
+  // Then anything overflow extends into 64b addressable space.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t range_size = core_range.range.size();
+if (stack_start_addresses.count(core_range.range.start()) > 0)
+  // Don't double save stacks.
+  continue;
+
+if (total_size + range_size < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();

clayborg wrote:

use `range_size` that you created above.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);

clayborg wrote:

Remove `sizeof(llvm::minidump::MemoryDescriptor)` from here since we account 
for it before this for loop. If this is now just the core range size, rename 
like `range_size`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -480,71 +559,64 @@ class ArchThreadContexts {
   }
 };
 
-// Function returns start and size of the memory region that contains
-// memory location pointed to by the current stack pointer.
-llvm::Expected>
-findStackHelper(const lldb::ProcessSP _sp, uint64_t rsp) {
-  MemoryRegionInfo range_info;
-  Status error = process_sp->GetMemoryRegionInfo(rsp, range_info);
-  // Skip failed memory region requests or any regions with no permissions.
-  if (error.Fail() || range_info.GetLLDBPermissions() == 0)
-return llvm::createStringError(
-std::errc::not_supported,
-"unable to load stack segment of the process");
-
-  // This is a duplicate of the logic in
-  // Process::SaveOffRegionsWithStackPointers but ultimately, we need to only
-  // save up from the start of the stack down to the stack pointer
-  const addr_t range_end = range_info.GetRange().GetRangeEnd();
-  const addr_t red_zone = process_sp->GetABI()->GetRedZoneSize();
-  const addr_t stack_head = rsp - red_zone;
-  if (stack_head > range_info.GetRange().GetRangeEnd()) {
-range_info.GetRange().SetRangeBase(stack_head);
-range_info.GetRange().SetByteSize(range_end - stack_head);
-  }
-
-  const addr_t addr = range_info.GetRange().GetRangeBase();
-  const addr_t size = range_info.GetRange().GetByteSize();
-
-  if (size == 0)
-return llvm::createStringError(std::errc::not_supported,
-   "stack segment of the process is empty");
-
-  return std::make_pair(addr, size);
+Status MinidumpFileBuilder::FixThreadStacks() {
+  Status error;
+  // If we have anything in the heap flush it.
+  FlushBufferToDisk();
+  m_core_file->SeekFromStart(m_thread_list_start);
+  for (auto  : m_thread_by_range_end) {
+// The thread objects will get a new memory descriptor added
+// When we are emitting the memory list and then we write it here
+const llvm::minidump::Thread  = pair.second;
+size_t bytes_to_write = sizeof(llvm::minidump::Thread);
+size_t bytes_written = bytes_to_write;
+error = m_core_file->Write(, bytes_written);

clayborg wrote:

We can do this in a later patch as the `sizeof(llvm::minidump::Thread)` won't 
exceed 32 bits


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",

clayborg wrote:

Change `"(%zu bytes) [%zx, %zx)"` to `"(%" PRIu64 " bytes [%" PRIx64 ", %" 
PRIx64 ")"`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges)
+max_size = std::max(max_size, core_range.range.size());
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status
+MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();

clayborg wrote:

uint64_t

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);

clayborg wrote:

remove static_casts

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;

clayborg wrote:

use `uint64_t`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -821,47 +908,285 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   Status error;
   size_t bytes_written;
 
-  bytes_written = header_size;
-  error = core_file->Write(, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  m_core_file->SeekFromStart(0);
+  bytes_written = HEADER_SIZE;
+  error = m_core_file->Write(, bytes_written);
+  if (error.Fail() || bytes_written != HEADER_SIZE) {
+if (bytes_written != HEADER_SIZE)
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
+  "Unable to write the minidump header (written %zd/%zd)",
+  bytes_written, HEADER_SIZE);
 return error;
   }
+  return error;
+}
 
-  // write data
-  bytes_written = m_data.GetByteSize();
-  error = core_file->Write(m_data.GetBytes(), bytes_written);
-  if (error.Fail() || bytes_written != m_data.GetByteSize()) {
-if (bytes_written != m_data.GetByteSize())
-  error.SetErrorStringWithFormat(
-  "unable to write the data (written %zd/%" PRIu64 ")", bytes_written,
-  m_data.GetByteSize());
-return error;
-  }
+size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
+  return m_data.GetByteSize() + m_saved_data_size;
+}
 
-  // write directories
+Status MinidumpFileBuilder::DumpDirectories() const {
+  Status error;
+  size_t bytes_written;
+  m_core_file->SeekFromStart(HEADER_SIZE);
   for (const Directory  : m_directories) {
-bytes_written = directory_size;
-error = core_file->Write(, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
+bytes_written = DIRECTORY_SIZE;
+error = m_core_file->Write(, bytes_written);
+if (error.Fail() || bytes_written != DIRECTORY_SIZE) {
+  if (bytes_written != DIRECTORY_SIZE)
 error.SetErrorStringWithFormat(
 "unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
+DIRECTORY_SIZE);
   return error;
 }
   }
 
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {

clayborg wrote:

Rename to match what it is returning and don't use `size_t`, this will fail on 
32 bit systems if we have a range over UINT32_MAX:
```
static uint64_t GetLargestRangeSize(const Process::CoreFileMemoryRanges 
) {

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0)
+  // Don't double save stacks.
+  continue;
+
+if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+} else {
+  ranges_64.push_back(core_range);
+}
+  }
+
+  error = AddMemoryList_32(ranges_32);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (!ranges_64.empty()) {
+error = AddMemoryList_64(ranges_64);
+if (error.Fail())
+  return error;
+  }
 
+  return FixThreadStacks();
+}
+
+Status MinidumpFileBuilder::DumpHeader() const {
   // write header
   llvm::minidump::Header header;
   header.Signature = static_cast(
   llvm::minidump::Header::MagicSignature);
   header.Version = static_cast(
   llvm::minidump::Header::MagicVersion);
   header.NumberOfStreams =
-  static_cast(GetDirectoriesNum());
+  static_cast(m_directories.size());
+  // We write the directories right after the header.
   header.StreamDirectoryRVA =
-  static_cast(GetCurrentDataEndOffset());
+  static_cast(HEADER_SIZE);

clayborg wrote:

remove static_cast, not needed.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
+}
+
+Status MinidumpFileBuilder::AddMemoryList_64(
+Process::CoreFileMemoryRanges ) {
+  Status error;
+  if (ranges.empty()) 
+return error;
+
+  error = AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());

clayborg wrote:

remove static casts

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -480,71 +559,64 @@ class ArchThreadContexts {
   }
 };
 
-// Function returns start and size of the memory region that contains
-// memory location pointed to by the current stack pointer.
-llvm::Expected>
-findStackHelper(const lldb::ProcessSP _sp, uint64_t rsp) {
-  MemoryRegionInfo range_info;
-  Status error = process_sp->GetMemoryRegionInfo(rsp, range_info);
-  // Skip failed memory region requests or any regions with no permissions.
-  if (error.Fail() || range_info.GetLLDBPermissions() == 0)
-return llvm::createStringError(
-std::errc::not_supported,
-"unable to load stack segment of the process");
-
-  // This is a duplicate of the logic in
-  // Process::SaveOffRegionsWithStackPointers but ultimately, we need to only
-  // save up from the start of the stack down to the stack pointer
-  const addr_t range_end = range_info.GetRange().GetRangeEnd();
-  const addr_t red_zone = process_sp->GetABI()->GetRedZoneSize();
-  const addr_t stack_head = rsp - red_zone;
-  if (stack_head > range_info.GetRange().GetRangeEnd()) {
-range_info.GetRange().SetRangeBase(stack_head);
-range_info.GetRange().SetByteSize(range_end - stack_head);
-  }
-
-  const addr_t addr = range_info.GetRange().GetRangeBase();
-  const addr_t size = range_info.GetRange().GetByteSize();
-
-  if (size == 0)
-return llvm::createStringError(std::errc::not_supported,
-   "stack segment of the process is empty");
-
-  return std::make_pair(addr, size);
+Status MinidumpFileBuilder::FixThreadStacks() {
+  Status error;
+  // If we have anything in the heap flush it.
+  FlushBufferToDisk();
+  m_core_file->SeekFromStart(m_thread_list_start);
+  for (auto  : m_thread_by_range_end) {
+// The thread objects will get a new memory descriptor added
+// When we are emitting the memory list and then we write it here
+const llvm::minidump::Thread  = pair.second;
+size_t bytes_to_write = sizeof(llvm::minidump::Thread);
+size_t bytes_written = bytes_to_write;
+error = m_core_file->Write(, bytes_written);

clayborg wrote:

We should probably change the underlying `Write(...)` function to not use 
`size_t` if it is as this will fail on 32 bit architectures, or we need to 
write at most SIZET_MAX

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  std::unordered_set stack_start_addresses;
+  for (const auto _range : ranges_32) {
+stack_start_addresses.insert(core_range.range.start());
+total_size += core_range.range.size();
+  }
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size +=
+  256 + (all_core_memory_ranges.size() - stack_start_addresses.size()) *
+sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0)
+  // Don't double save stacks.
+  continue;
+
+if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+} else {
+  ranges_64.push_back(core_range);
+}
+  }
+
+  error = AddMemoryList_32(ranges_32);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (!ranges_64.empty()) {
+error = AddMemoryList_64(ranges_64);
+if (error.Fail())
+  return error;
+  }
 
+  return FixThreadStacks();
+}
+
+Status MinidumpFileBuilder::DumpHeader() const {
   // write header
   llvm::minidump::Header header;
   header.Signature = static_cast(
   llvm::minidump::Header::MagicSignature);
   header.Version = static_cast(
   llvm::minidump::Header::MagicVersion);
   header.NumberOfStreams =
-  static_cast(GetDirectoriesNum());
+  static_cast(m_directories.size());

clayborg wrote:

remove static_cast, not needed.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());

clayborg wrote:

The assignment operator can and must work for these 
`llvm::support::ulittleXX_t` values, we should take advantage of them and keep 
the code cleaner. Removing all static_casts makes this code easier to read and 
avoids people making copy/paste of similar code in the future. I know there 
were some static casts before this patch, but we should remove them.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -791,26 +805,99 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(

clayborg wrote:

Add a comment here:
```
// We first save the thread stacks to ensure they fit in the first UINT32_MAX 
// bytes of the core file. Thread structures in minidump files can only use
// 32 bit memory descriptiors, so we emit them first to ensure the memory is
// in accessible with a 32 bit offset.
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Greg Clayton via lldb-commits


@@ -20,25 +20,96 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += HEADER_SIZE;

clayborg wrote:

Should't this be:
```
m_saved_data_size = HEADER_SIZE;
```
There is no need to use `+=` right?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Jacob Lalonde via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);

Jlalond wrote:

Messaged offline, but it doesn't appear all the little endian types support 
conversion. Specifically ulittle64_t and ulittle_t for the stream type. I think 
we should fix this in a followup, and add a formatter for little endian types.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Jacob Lalonde via lldb-commits


@@ -858,10 +923,224 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+Status MinidumpFileBuilder::AddMemoryList_32(
+const Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;

Jlalond wrote:

Done. Albeit the `m_data` buffer that the class uses does get used and then 
reallocated when we call `Clear()` in flush to disk. May want to look into 
keeping a write index and a range...

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-17 Thread Jacob Lalonde via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());

Jlalond wrote:

I'm torn on the static casts. I know the little endian support types can 
support big endian assignment, but I think the static cast makes it very 
explicit that these values have to be little endian

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -791,26 +812,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();

clayborg wrote:

Merge this `total_size` calculation stuff into the loop above on line 836. No 
need to iterate over this twice.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);

clayborg wrote:

You can just assign these values with out using the `static_cast` (and yes 
there are many places in this code doing these static_cast calls unecessarily:
```
 descriptor.StartOfMemoryRange = addr;
 descriptor.Memory.DataSize = bytes_read;
 descriptor.Memory.RVA = offset_for_data;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
+}
+
+Status MinidumpFileBuilder::AddMemoryList_64(
+Process::CoreFileMemoryRanges ) {
+  Status error;
+  if (ranges.empty()) 
+return error;
+
+  error = AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle64_t));
+  // Capture the starting offset for all the descriptors so we can clean them 
up
+  // if needed.
+  offset_t starting_offset = GetCurrentDataEndOffset() + 
sizeof(llvm::support::ulittle64_t);
+  // The base_rva needs to start after the directories, which is right after
+  // this 8 byte variable.
+  offset_t base_rva = starting_offset + (ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  llvm::support::ulittle64_t memory_ranges_base_rva =
+  static_cast(base_rva);
+  m_data.AppendData(_ranges_base_rva,
+sizeof(llvm::support::ulittle64_t));
+
+  bool cleanup_required = false;
+  std::vector descriptors;
+  // Enumerate the ranges and create the memory descriptors so we can append
+  // them first
+  for (const auto core_range : ranges) {
+// Add the space required to store the memory descriptor
+MemoryDescriptor_64 memory_desc;
+memory_desc.StartOfMemoryRange =
+static_cast(core_range.range.start());
+memory_desc.DataSize =
+static_cast(core_range.range.size());

clayborg wrote:

remove static cast

https://github.com/llvm/llvm-project/pull/95312
___

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
+}
+
+Status MinidumpFileBuilder::AddMemoryList_64(
+Process::CoreFileMemoryRanges ) {
+  Status error;
+  if (ranges.empty()) 
+return error;
+
+  error = AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle64_t));
+  // Capture the starting offset for all the descriptors so we can clean them 
up
+  // if needed.
+  offset_t starting_offset = GetCurrentDataEndOffset() + 
sizeof(llvm::support::ulittle64_t);
+  // The base_rva needs to start after the directories, which is right after
+  // this 8 byte variable.
+  offset_t base_rva = starting_offset + (ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+  llvm::support::ulittle64_t memory_ranges_base_rva =
+  static_cast(base_rva);

clayborg wrote:

no static cast

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -20,25 +20,104 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/RangeMap.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
+  // (corresponding memory list for stacks) And an additional memory list for
+  // non-stacks.
+  lldb_private::Target  = m_process_sp->GetTarget();
+  m_expected_directories = 6;
+  // Check if OS is linux and reserve directory space for all linux specific 
breakpad extension directories.
+  if (target.GetArchitecture().GetTriple().getOS() ==
+  llvm::Triple::OSType::Linux)
+m_expected_directories += 9;
+
+  // Go through all of the threads and check for exceptions.
+  lldb_private::ThreadList thread_list = m_process_sp->GetThreadList();
+  const uint32_t num_threads = thread_list.GetSize();
+  for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+if (stop_info_sp &&
+stop_info_sp->GetStopReason() == StopReason::eStopReasonException) {
+  m_expected_directories++;
+}
+  }
+
+  // Now offset the file by the directores so we can write them in later.
+  offset_t directory_offset = m_expected_directories * directory_size;
+  m_saved_data_size += directory_offset;
+  Status error;
+  size_t zeroes = 0; // 8 0's
+  size_t remaining_bytes = m_saved_data_size;
+  while (remaining_bytes > 0) {
+// Keep filling in zero's until we preallocate enough space for the header
+// and directory sections.
+size_t bytes_written = std::min(remaining_bytes, sizeof(size_t));
+error = m_core_file->Write(, bytes_written);
+if (error.Fail()) {
+  error.SetErrorStringWithFormat(
+"Unable to write header and directory padding (written %zd/%zd)",
+remaining_bytes - m_saved_data_size, m_saved_data_size);
+  break;
+}
+
+remaining_bytes -= bytes_written;
+  }

clayborg wrote:

Just set the file position in the `m_core_file`:
```
m_core_file->SeekFromStart(m_saved_data_size);
```
And remove this entire while loop.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -28,17 +29,90 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;

clayborg wrote:

Is there a better name for `m_saved_data_size`? 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+  if (error.Fail())
+return error;
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());

clayborg wrote:

```
llvm::support::ulittle32_t memory_ranges_num(descriptors.size());
```
No need for static_cast right. Lots of places already had these incorrect extra 
static_cast calls..

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -797,20 +794,89 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size += 256 + (ranges_64.size() - stack_start_addresses.size()) *
+  sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0) {
+  // Don't double save stacks.
+  continue;
+} else if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+  total_size += sizeof(llvm::minidump::MemoryDescriptor);

clayborg wrote:

This can still be just:
```
total_size += size_to_add;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -81,38 +82,42 @@ Status 
MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
   // Now offset the file by the directores so we can write them in later.
   offset_t directory_offset = m_expected_directories * directory_size;
   m_saved_data_size += directory_offset;
-  // Replace this when we make a better way to do this.
   Status error;
-  Header empty_header;
-  size_t bytes_written;
-  bytes_written = header_size;
-  error = m_core_file->Write(_header, bytes_written);
-  if (error.Fail() || bytes_written != header_size) {
-if (bytes_written != header_size)
+  size_t zeroes = 0; // 8 0's
+  size_t remaining_bytes = m_saved_data_size;
+  while (remaining_bytes > 0) {
+// Keep filling in zero's until we preallocate enough space for the header
+// and directory sections.
+size_t bytes_written = std::min(remaining_bytes, sizeof(size_t));
+error = m_core_file->Write(, bytes_written);
+if (error.Fail()) {
   error.SetErrorStringWithFormat(
-  "unable to write the header (written %zd/%zd)", bytes_written,
-  header_size);
-return error;
-  }
-
-  for (uint i = 0; i < m_expected_directories; i++) {
-size_t bytes_written;
-bytes_written = directory_size;
-Directory empty_directory;
-error = m_core_file->Write(_directory, bytes_written);
-if (error.Fail() || bytes_written != directory_size) {
-  if (bytes_written != directory_size)
-error.SetErrorStringWithFormat(
-"unable to write the directory (written %zd/%zd)", bytes_written,
-directory_size);
-  return error;
+"Unable to write header and directory padding (written %zd/%zd)",
+remaining_bytes - m_saved_data_size, m_saved_data_size);
+  break;
 }
+
+remaining_bytes -= bytes_written;
   }

clayborg wrote:

Remove this while look and complex functionality and just call:
```
m_core_file->SeekFromStart(m_saved_data_size);
```
No need to write zeroes.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -791,26 +812,101 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   size_t size = memory_buffer->getBufferSize();
   if (size == 0)
 continue;
-  AddDirectory(stream, size);
+  error = AddDirectory(stream, size);
+  if (error.Fail())
+return error;
   m_data.AppendData(memory_buffer->getBufferStart(), size);
 }
   }
+
+  return error;
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemoryList(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
+
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size += 256 + (all_core_memory_ranges.size() - 
stack_start_addresses.size()) *
+  sizeof(llvm::minidump::MemoryDescriptor_64);
 
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0) 
+  // Don't double save stacks.
+  continue;
+
+if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+  total_size += sizeof(llvm::minidump::MemoryDescriptor);
+} else {
+  ranges_64.push_back(core_range);
+}
+  }
+
+  error = AddMemoryList_32(ranges_32);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (ranges_64.size() > 0) {

clayborg wrote:

```
if (!ranges_64.empty()) {
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }
+  return max_size;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_32(
+  Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  if (ranges.size() == 0)
+return error;
+
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  auto data_up = std::make_unique(GetLargestRange(ranges), 0);
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+const addr_t end = core_range.range.end();
+
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_end.count(end) > 0)
+  m_thread_by_range_end[end].Stack = descriptor;
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  error = AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));

clayborg wrote:

indent ok here? Run clang-format on this

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-14 Thread Greg Clayton via lldb-commits


@@ -858,10 +953,247 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+static size_t GetLargestRange(const Process::CoreFileMemoryRanges ) {
+  size_t max_size = 0;
+  for (const auto _range : ranges) {
+max_size = std::max(max_size, core_range.range.size());
+  }

clayborg wrote:

remove `{}` from single line for statement per llvm coding guidelines

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits

jeffreytan81 wrote:

Can this be landed safely? Do we need to update consumer side to support memory 
list 64? For example, if this diff is landed, and a user tries to save a 
minidump with memory list 64, if there is no consumer side support, will lldb 
crash?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -50,48 +60,75 @@ class MinidumpFileBuilder {
 
   ~MinidumpFileBuilder() = default;
 
+  lldb_private::Status AddHeaderAndCalculateDirectories();

jeffreytan81 wrote:

I would add comment to clarify that this is partially done and which fields 
require later fixup. 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -65,56 +66,52 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP 
_sp,
   if (!process_sp)
 return false;
 
-  MinidumpFileBuilder builder;
-
-  Target  = process_sp->GetTarget();
-
-  Log *log = GetLog(LLDBLog::Object);
-  error = builder.AddSystemInfo(target.GetArchitecture().GetTriple());
-  if (error.Fail()) {
-LLDB_LOG(log, "AddSystemInfo failed: %s", error.AsCString());
+  llvm::Expected maybe_core_file = FileSystem::Instance().Open(
+  outfile, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate);
+  if (!maybe_core_file) {
+error = maybe_core_file.takeError();
 return false;
   }
+  MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp);
 
-  error = builder.AddModuleList(target);
+  Target  = process_sp->GetTarget();
+  builder.AddHeaderAndCalculateDirectories();
+  Log *log = GetLog(LLDBLog::Object);
+  error = builder.AddSystemInfo();
   if (error.Fail()) {
-LLDB_LOG(log, "AddModuleList failed: %s", error.AsCString());
+LLDB_LOGF(log, "AddSystemInfo failed: %s", error.AsCString());
 return false;
   }
 
-  builder.AddMiscInfo(process_sp);
+  builder.AddModuleList();

jeffreytan81 wrote:

Let's handle the failure from `AddModuleList()`. I am pretty sure I have seen a 
failure once. 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -65,56 +66,52 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP 
_sp,
   if (!process_sp)
 return false;
 
-  MinidumpFileBuilder builder;
-
-  Target  = process_sp->GetTarget();
-
-  Log *log = GetLog(LLDBLog::Object);
-  error = builder.AddSystemInfo(target.GetArchitecture().GetTriple());
-  if (error.Fail()) {
-LLDB_LOG(log, "AddSystemInfo failed: %s", error.AsCString());
+  llvm::Expected maybe_core_file = FileSystem::Instance().Open(

jeffreytan81 wrote:

Let's add a block of comment explaining the high level of the serialization 
logic. Most importantly:
1. Physical layout (header first, directories next, memory list has to be the 
last and why)
2. Later fixup needs to be done to header/directories after everything to the 
important fields
3. Later fixup needs to be done to thread.stack field after dumping memory list 
so that we can avoid duplication

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -50,48 +60,75 @@ class MinidumpFileBuilder {
 
   ~MinidumpFileBuilder() = default;
 
+  lldb_private::Status AddHeaderAndCalculateDirectories();
   // Add SystemInfo stream, used for storing the most basic information
   // about the system, platform etc...
-  lldb_private::Status AddSystemInfo(const llvm::Triple _triple);
+  lldb_private::Status AddSystemInfo();
   // Add ModuleList stream, containing information about all loaded modules
   // at the time of saving minidump.
-  lldb_private::Status AddModuleList(lldb_private::Target );
+  lldb_private::Status AddModuleList();
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+  lldb_private::Status AddThreadList();
   // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
+  void AddExceptions();
   // Add MiscInfo stream, mainly providing ProcessId
-  void AddMiscInfo(const lldb::ProcessSP _sp);
+  void AddMiscInfo();
   // Add informative files about a Linux process
-  void AddLinuxFileStreams(const lldb::ProcessSP _sp);
-  // Dump the prepared data into file. In case of the failure data are
-  // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  void AddLinuxFileStreams();
+
+  lldb_private::Status AddMemory(lldb::SaveCoreStyle core_style);
+
+  // Run cleanup and write all remaining bytes to file
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();

jeffreytan81 wrote:

1. You should add comment explaining what is "FixThreads()" doing and why we 
need it. 
2. `FixThreads` is a very generic name, but you are really fixing up the stack 
field only. So rename to "FixupThreadStack()" to be more specific.


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -797,20 +794,89 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  std::set stack_start_addresses;

jeffreytan81 wrote:

If you do not need ordering of the elements in the set, use 
`std::unordered_set`.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -480,42 +557,32 @@ class ArchThreadContexts {
   }
 };
 
-// Function returns start and size of the memory region that contains
-// memory location pointed to by the current stack pointer.
-llvm::Expected>
-findStackHelper(const lldb::ProcessSP _sp, uint64_t rsp) {
-  MemoryRegionInfo range_info;
-  Status error = process_sp->GetMemoryRegionInfo(rsp, range_info);
-  // Skip failed memory region requests or any regions with no permissions.
-  if (error.Fail() || range_info.GetLLDBPermissions() == 0)
-return llvm::createStringError(
-std::errc::not_supported,
-"unable to load stack segment of the process");
-
-  // This is a duplicate of the logic in
-  // Process::SaveOffRegionsWithStackPointers but ultimately, we need to only
-  // save up from the start of the stack down to the stack pointer
-  const addr_t range_end = range_info.GetRange().GetRangeEnd();
-  const addr_t red_zone = process_sp->GetABI()->GetRedZoneSize();
-  const addr_t stack_head = rsp - red_zone;
-  if (stack_head > range_info.GetRange().GetRangeEnd()) {
-range_info.GetRange().SetRangeBase(stack_head);
-range_info.GetRange().SetByteSize(range_end - stack_head);
-  }
-
-  const addr_t addr = range_info.GetRange().GetRangeBase();
-  const addr_t size = range_info.GetRange().GetByteSize();
-
-  if (size == 0)
-return llvm::createStringError(std::errc::not_supported,
-   "stack segment of the process is empty");
-
-  return std::make_pair(addr, size);
+Status MinidumpFileBuilder::FixThreads() {
+  Status error;
+  // If we have anything in the heap flush it.
+  FlushToDisk();
+  m_core_file->SeekFromStart(m_thread_list_start);
+  for (auto  : m_thread_by_range_start) {
+// The thread objects will get a new memory descriptor added
+// When we are emitting the memory list and then we write it here
+llvm::minidump::Thread thread = pair.second;

jeffreytan81 wrote:

I do not think you need to copy:
```
const llvm::minidump::Thread& thread
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -50,48 +60,75 @@ class MinidumpFileBuilder {
 
   ~MinidumpFileBuilder() = default;
 
+  lldb_private::Status AddHeaderAndCalculateDirectories();
   // Add SystemInfo stream, used for storing the most basic information
   // about the system, platform etc...
-  lldb_private::Status AddSystemInfo(const llvm::Triple _triple);
+  lldb_private::Status AddSystemInfo();
   // Add ModuleList stream, containing information about all loaded modules
   // at the time of saving minidump.
-  lldb_private::Status AddModuleList(lldb_private::Target );
+  lldb_private::Status AddModuleList();
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+  lldb_private::Status AddThreadList();
   // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
+  void AddExceptions();
   // Add MiscInfo stream, mainly providing ProcessId
-  void AddMiscInfo(const lldb::ProcessSP _sp);
+  void AddMiscInfo();
   // Add informative files about a Linux process
-  void AddLinuxFileStreams(const lldb::ProcessSP _sp);
-  // Dump the prepared data into file. In case of the failure data are
-  // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  void AddLinuxFileStreams();
+
+  lldb_private::Status AddMemory(lldb::SaveCoreStyle core_style);
+
+  // Run cleanup and write all remaining bytes to file
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();
+  lldb_private::Status FlushToDisk();
+
+  lldb_private::Status DumpHeader() const;
+  lldb_private::Status DumpDirectories() const;
+  bool CheckIf_64Bit(const size_t size);
   // Add directory of StreamType pointing to the current end of the prepared
   // file with the specified size.
-  void AddDirectory(llvm::minidump::StreamType type, size_t stream_size);
-  size_t GetCurrentDataEndOffset() const;
-
-  // Stores directories to later put them at the end of minidump file
+  void AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size);
+  lldb::offset_t GetCurrentDataEndOffset() const;
+  // Stores directories to fill in later
   std::vector m_directories;
+  // When we write off the threads for the first time, we need to clean them up
+  // and give them the correct RVA once we write the stack memory list.
+  std::map m_thread_by_range_start;
   // Main data buffer consisting of data without the minidump header and
   // directories
   lldb_private::DataBufferHeap m_data;
+  lldb::ProcessSP m_process_sp;
+
+  uint m_expected_directories = 0;
+  uint64_t m_saved_data_size = 0;
+  lldb::offset_t m_thread_list_start = 0;
+  // We set the max write amount to 128 mb, this is arbitrary
+  // but we want to try to keep the size of m_data small
+  // and we will only exceed a 128 mb buffer if we get a memory region
+  // that is larger than 128 mb.
+  static constexpr size_t m_write_chunk_max = (1024 * 1024 * 128);
+
+  static constexpr size_t header_size = sizeof(llvm::minidump::Header);
+  static constexpr size_t directory_size = sizeof(llvm::minidump::Directory);

jeffreytan81 wrote:

The naming convention is not consistent. For constexpr, either 
`MAX_WRITE_CHUNK` or `MaxChunkSize` for readability. 
Similar for `HEADER_SIZE` and `DIRECTORY_SIZE`. 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();

jeffreytan81 wrote:

As you are describing it, you can see this method is doing two things. I do not 
see the benefit of grouping them into one confusing named function. Let's split 
it into two functions:
1. FixupHeaderDirectory()
2. FlushToFile()


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread via lldb-commits


@@ -50,48 +60,75 @@ class MinidumpFileBuilder {
 
   ~MinidumpFileBuilder() = default;
 
+  lldb_private::Status AddHeaderAndCalculateDirectories();
   // Add SystemInfo stream, used for storing the most basic information
   // about the system, platform etc...
-  lldb_private::Status AddSystemInfo(const llvm::Triple _triple);
+  lldb_private::Status AddSystemInfo();
   // Add ModuleList stream, containing information about all loaded modules
   // at the time of saving minidump.
-  lldb_private::Status AddModuleList(lldb_private::Target );
+  lldb_private::Status AddModuleList();
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+  lldb_private::Status AddThreadList();
   // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
+  void AddExceptions();
   // Add MiscInfo stream, mainly providing ProcessId
-  void AddMiscInfo(const lldb::ProcessSP _sp);
+  void AddMiscInfo();
   // Add informative files about a Linux process
-  void AddLinuxFileStreams(const lldb::ProcessSP _sp);
-  // Dump the prepared data into file. In case of the failure data are
-  // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  void AddLinuxFileStreams();
+
+  lldb_private::Status AddMemory(lldb::SaveCoreStyle core_style);
+
+  // Run cleanup and write all remaining bytes to file
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb_private::Process::CoreFileMemoryRanges );

jeffreytan81 wrote:

I would simply call `AddMemoryList64`, `AddMemoryList32` and `Is64Bit`.
Let's be consistent about the member function naming convention. 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();
+  lldb_private::Status FlushToDisk();
+
+  lldb_private::Status DumpHeader() const;
+  lldb_private::Status DumpDirectories() const;
+  bool CheckIf_64Bit(const size_t size);
   // Add directory of StreamType pointing to the current end of the prepared
   // file with the specified size.
-  void AddDirectory(llvm::minidump::StreamType type, size_t stream_size);
-  size_t GetCurrentDataEndOffset() const;
-
-  // Stores directories to later put them at the end of minidump file
+  void AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size);
+  lldb::addr_t GetCurrentDataEndOffset() const;
+  // Stores directories to fill in later
   std::vector m_directories;
+  // When we write off the threads for the first time, we need to clean them up
+  // and give them the correct RVA once we write the stack memory list.
+  std::map m_thread_by_range_start;

clayborg wrote:

If it is an address then `lldb::addr_t` is the right choice. I must have 
confused this with another location that needed to use `lldb::offset_t` for an 
offset that was being stored as a `lldb::addr_t`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -858,10 +923,224 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+Status MinidumpFileBuilder::AddMemoryList_32(
+const Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+auto data_up = std::make_unique(size, 0);
+
+LLDB_LOGF(log,
+  "/AddMemoryList/AddMemory/ %zu/%zu reading memory for region "
+  "(%zu bytes) [%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+m_process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_start.count(addr) > 0) {
+  m_thread_by_range_start[addr].Stack = descriptor;
+}
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_64(
+const Process::CoreFileMemoryRanges ) {
+  AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle64_t));
+  llvm::support::ulittle64_t memory_ranges_base_rva =
+  static_cast(GetCurrentDataEndOffset());
+  m_data.AppendData(_ranges_base_rva,
+sizeof(llvm::support::ulittle64_t));
+  // Capture the starting offset, so we can do cleanup later if needed.
+  uint64_t starting_offset = GetCurrentDataEndOffset();
+
+  bool cleanup_required = false;
+  std::vector descriptors;
+  // Enumerate the ranges and create the memory descriptors so we can append
+  // them first
+  for (const auto core_range : ranges) {
+// Add the space required to store the memory descriptor
+MemoryDescriptor_64 memory_desc;
+memory_desc.StartOfMemoryRange =
+static_cast(core_range.range.start());
+memory_desc.DataSize =
+static_cast(core_range.range.size());
+descriptors.push_back(memory_desc);
+// Now write this memory descriptor to the buffer.
+m_data.AppendData(_desc, sizeof(MemoryDescriptor_64));
+  }
+
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  for (const auto _range : ranges) {
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+auto data_up = std::make_unique(size, 0);

clayborg wrote:

move this out of the for loop and have it contain `max_size` bytes just like in 
the 32 bit variant of this function.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -28,17 +29,90 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;

clayborg wrote:

Can we have data already in the file here? If not we should assign 
`m_saved_data_size` here:
```
m_saved_data_size = header_size;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -28,17 +29,90 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
+#include "llvm/TargetParser/Triple.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories() {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
+  // (corresponding memory list for stacks) And an additional memory list for
+  // non-stacks.
+
+  lldb_private::Target  = m_process_sp->GetTarget();
+  m_expected_directories = 6;
+  // Check if OS is linux

clayborg wrote:

```
// Check if OS is linux and reserve directory space for all linux specific 
breakpad extension directories.
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -858,10 +937,225 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+Status MinidumpFileBuilder::AddMemoryList_32(
+const ProcessSP _sp, const Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+auto data_up = std::make_unique(size, 0);

clayborg wrote:

re-use the one copy of `data_up` from above, just remove this line.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -50,48 +60,75 @@ class MinidumpFileBuilder {
 
   ~MinidumpFileBuilder() = default;
 
+  lldb_private::Status AddHeaderAndCalculateDirectories();
   // Add SystemInfo stream, used for storing the most basic information
   // about the system, platform etc...
-  lldb_private::Status AddSystemInfo(const llvm::Triple _triple);
+  lldb_private::Status AddSystemInfo();
   // Add ModuleList stream, containing information about all loaded modules
   // at the time of saving minidump.
-  lldb_private::Status AddModuleList(lldb_private::Target );
+  lldb_private::Status AddModuleList();
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+  lldb_private::Status AddThreadList();
   // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
+  void AddExceptions();
   // Add MiscInfo stream, mainly providing ProcessId
-  void AddMiscInfo(const lldb::ProcessSP _sp);
+  void AddMiscInfo();
   // Add informative files about a Linux process
-  void AddLinuxFileStreams(const lldb::ProcessSP _sp);
-  // Dump the prepared data into file. In case of the failure data are
-  // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  void AddLinuxFileStreams();
+
+  lldb_private::Status AddMemory(lldb::SaveCoreStyle core_style);

clayborg wrote:

I would leave this named the same as it was before as `AddMemoryList` and move 
it back up to where it used to be in this source file

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -858,10 +937,225 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+Status MinidumpFileBuilder::AddMemoryList_32(
+const ProcessSP _sp, const Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+auto data_up = std::make_unique(size, 0);
+
+LLDB_LOGF(
+log,
+"AddMemoryList %zu/%zu reading memory for region (%zu bytes) [%zx, 
%zx)",
+region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_start.count(addr) > 0) {
+  m_thread_by_range_start[addr].Stack = descriptor;
+}

clayborg wrote:

Still need to remove these braces from this if

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -858,10 +923,224 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+Status MinidumpFileBuilder::AddMemoryList_32(
+const Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;

clayborg wrote:

Make on DataBufferHeap outside of this loop and re-use it:
```
lldb::offset_t max_size = 0;
for (const auto _range : ranges) {
  if (core_range.renge.size() > max_size)
max_size = core_range.renge.size();
}
auto data_up = std::make_unique(max_size, 0);
```

auto data_up = std::make_unique(size, 0);

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -797,20 +794,89 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size += 256 + (ranges_64.size() - stack_start_addresses.size()) *
+  sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0) {
+  // Don't double save stacks.
+  continue;
+} else if (total_size + size_to_add < UINT32_MAX) {
+  ranges_32.push_back(core_range);
+  total_size += core_range.range.size();
+  total_size += sizeof(llvm::minidump::MemoryDescriptor);

clayborg wrote:

Change these two lines to:
```
total_size += size_to_add;
```


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -797,20 +794,89 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_32;
+  Process::CoreFileMemoryRanges ranges_64;
+  error = m_process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
+  if (error.Fail())
+return error;
 
+  std::set stack_start_addresses;
+  for (const auto _range : ranges_32)
+stack_start_addresses.insert(core_range.range.start());
+
+  uint64_t total_size =
+  ranges_32.size() * sizeof(llvm::minidump::MemoryDescriptor);
+  for (const auto _range : ranges_32)
+total_size += core_range.range.size();
+
+  if (total_size >= UINT32_MAX) {
+error.SetErrorStringWithFormat("Unable to write minidump. Stack memory "
+   "exceeds 32b limit. (Num Stacks %zu)",
+   ranges_32.size());
+return error;
+  }
+
+  Process::CoreFileMemoryRanges all_core_memory_ranges;
+  if (core_style != SaveCoreStyle::eSaveCoreStackOnly) {
+error = m_process_sp->CalculateCoreFileSaveRanges(core_style,
+  all_core_memory_ranges);
+if (error.Fail())
+  return error;
+  }
+
+  // We need to calculate the MemoryDescriptor size in the worst case
+  // Where all memory descriptors are 64b. We also leave some additional 
padding
+  // So that we convert over to 64b with space to spare. This does not waste
+  // space in the dump But instead converts some memory from being in the
+  // memorylist_32 to the memorylist_64.
+  total_size += 256 + (ranges_64.size() - stack_start_addresses.size()) *
+  sizeof(llvm::minidump::MemoryDescriptor_64);
+
+  for (const auto _range : all_core_memory_ranges) {
+addr_t size_to_add =
+core_range.range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+if (stack_start_addresses.count(core_range.range.start()) > 0) {
+  // Don't double save stacks.
+  continue;
+} else if (total_size + size_to_add < UINT32_MAX) {

clayborg wrote:

No need for `else if` if we continue:
```
if (stack_start_addresses.count(core_range.range.start()) > 0)
  continue;  // Stacks are already in ranges_32

if (total_size + size_to_add < UINT32_MAX)
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();

clayborg wrote:

It would be nice to just have a `Finalize()` that does what `CompleteFile` and 
`FinalizeFile` and `WriteAndFinish` would do?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits

https://github.com/clayborg edited 
https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits

https://github.com/clayborg requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -858,10 +937,225 @@ Status MinidumpFileBuilder::Dump(lldb::FileUP 
_file) const {
   return error;
 }
 
-size_t MinidumpFileBuilder::GetDirectoriesNum() const {
-  return m_directories.size();
+Status MinidumpFileBuilder::AddMemoryList_32(
+const ProcessSP _sp, const Process::CoreFileMemoryRanges ) {
+  std::vector descriptors;
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  for (const auto _range : ranges) {
+// Take the offset before we write.
+const size_t offset_for_data = GetCurrentDataEndOffset();
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+auto data_up = std::make_unique(size, 0);
+
+LLDB_LOGF(
+log,
+"AddMemoryList %zu/%zu reading memory for region (%zu bytes) [%zx, 
%zx)",
+region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail() || bytes_read == 0) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, error: 
%s",
+bytes_read, error.AsCString());
+  // Just skip sections with errors or zero bytes in 32b mode
+  continue;
+} else if (bytes_read != size) {
+  LLDB_LOGF(log, "Memory region at: %zu failed to read %zu bytes", addr,
+size);
+}
+
+MemoryDescriptor descriptor;
+descriptor.StartOfMemoryRange =
+static_cast(addr);
+descriptor.Memory.DataSize =
+static_cast(bytes_read);
+descriptor.Memory.RVA =
+static_cast(offset_for_data);
+descriptors.push_back(descriptor);
+if (m_thread_by_range_start.count(addr) > 0) {
+  m_thread_by_range_start[addr].Stack = descriptor;
+}
+
+// Add the data to the buffer, flush as needed.
+error = AddData(data_up->GetBytes(), bytes_read);
+if (error.Fail())
+  return error;
+  }
+
+  // Add a directory that references this list
+  // With a size of the number of ranges as a 32 bit num
+  // And then the size of all the ranges
+  AddDirectory(StreamType::MemoryList,
+   sizeof(llvm::support::ulittle32_t) +
+   descriptors.size() *
+   sizeof(llvm::minidump::MemoryDescriptor));
+
+  llvm::support::ulittle32_t memory_ranges_num =
+  static_cast(descriptors.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle32_t));
+  // For 32b we can get away with writing off the descriptors after the data.
+  // This means no cleanup loop needed.
+  m_data.AppendData(descriptors.data(),
+descriptors.size() * sizeof(MemoryDescriptor));
+
+  return error;
 }
 
-size_t MinidumpFileBuilder::GetCurrentDataEndOffset() const {
-  return sizeof(llvm::minidump::Header) + m_data.GetByteSize();
+Status MinidumpFileBuilder::AddMemoryList_64(
+const ProcessSP _sp, const Process::CoreFileMemoryRanges ) {
+  AddDirectory(StreamType::Memory64List,
+   (sizeof(llvm::support::ulittle64_t) * 2) +
+   ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64));
+
+  llvm::support::ulittle64_t memory_ranges_num =
+  static_cast(ranges.size());
+  m_data.AppendData(_ranges_num, sizeof(llvm::support::ulittle64_t));
+  llvm::support::ulittle64_t memory_ranges_base_rva =
+  static_cast(GetCurrentDataEndOffset());
+  m_data.AppendData(_ranges_base_rva,
+sizeof(llvm::support::ulittle64_t));
+  // Capture the starting offset, so we can do cleanup later if needed.
+  uint64_t starting_offset = GetCurrentDataEndOffset();
+
+  bool cleanup_required = false;
+  std::vector descriptors;
+  // Enumerate the ranges and create the memory descriptors so we can append
+  // them first
+  for (const auto core_range : ranges) {
+// Add the space required to store the memory descriptor
+MemoryDescriptor_64 memory_desc;
+memory_desc.StartOfMemoryRange =
+static_cast(core_range.range.start());
+memory_desc.DataSize =
+static_cast(core_range.range.size());
+descriptors.push_back(memory_desc);
+// Now write this memory descriptor to the buffer.
+m_data.AppendData(_desc, sizeof(MemoryDescriptor_64));
+  }
+
+  Status error;
+  Log *log = GetLog(LLDBLog::Object);
+  size_t region_index = 0;
+  for (const auto _range : ranges) {
+const addr_t addr = core_range.range.start();
+const addr_t size = core_range.range.size();
+auto data_up = std::make_unique(size, 0);
+
+LLDB_LOGF(log,
+  "AddMemoryList_64 %zu/%zu reading memory for region (%zu bytes) "
+  "[%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
+++region_index;
+
+const size_t bytes_read =
+process_sp->ReadMemory(addr, data_up->GetBytes(), size, error);
+if (error.Fail()) {
+  LLDB_LOGF(log, "Failed to read memory region. Bytes read: %zu, 

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);

clayborg wrote:

yeah, always good to minimize code changes to make reviewing easier

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits

https://github.com/Jlalond edited 
https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }

Jlalond wrote:

I would say we should error, especially with the reduced stacks since !92002 if 
the stacks did exceed 4gb this would be a case where we wouldn't fully be able 
to support the user.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();

Jlalond wrote:

To start, this is not a good name, but we need at least two methods: 
 - One method to just write data from the buffer to the current end of the file
 - One method to finalize and run header/directory cleanup.

When trying to get this done I couldn't come up with a good name, so I am 
soliciting ideas. I think going forward some better version could be 
`CompleteFile()` `FinalizeFile()` `WriteAndFinish()` but I don't like any of 
them

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();
+  lldb_private::Status FlushToDisk();
+
+  lldb_private::Status DumpHeader() const;
+  lldb_private::Status DumpDirectories() const;
+  bool CheckIf_64Bit(const size_t size);
   // Add directory of StreamType pointing to the current end of the prepared
   // file with the specified size.
-  void AddDirectory(llvm::minidump::StreamType type, size_t stream_size);
-  size_t GetCurrentDataEndOffset() const;
-
-  // Stores directories to later put them at the end of minidump file
+  void AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size);
+  lldb::addr_t GetCurrentDataEndOffset() const;
+  // Stores directories to fill in later
   std::vector m_directories;
+  // When we write off the threads for the first time, we need to clean them up
+  // and give them the correct RVA once we write the stack memory list.
+  std::map m_thread_by_range_start;
   // Main data buffer consisting of data without the minidump header and
   // directories
   lldb_private::DataBufferHeap m_data;
+  uint m_expected_directories = 0;
+  uint64_t m_saved_data_size = 0;
+  size_t m_thread_list_start = 0;
+  // We set the max write amount to 128 mb
+  // Linux has a signed 32b - some buffer on writes
+  // and we have guarauntee a user memory region / 'object' could be over 2gb
+  // now that we support 64b memory dumps.
+  static constexpr size_t m_write_chunk_max = (1024 * 1024 * 128);

Jlalond wrote:

Avoiding OS limitations was the goal. Originally when I was testing large 
minidumps, I created a large array, that was 5.2gb in size. Linux has a max 
write byte size that is slightly less than `SSIZE_T` max. However that also 
ends up being platform specific, and we should probably make the write size the 
architecture byte width max value for `SSIZE_T`.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.
+  Process::CoreFileMemoryRanges ranges;
+  error = process_sp->CalculateCoreFileSaveRanges(core_style, ranges);
+  if (error.Fail()) {
+return error;
+  }
+
+  uint64_t total_size =
+  256 + (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));

Jlalond wrote:

It's actually arbitrary. I wanted to make sure we had some byte aligned padding 
before the end of the file, so that all the MemoryDescriptors64 could be 32b 
addressable with the data after them.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();
+  lldb_private::Status FlushToDisk();
+
+  lldb_private::Status DumpHeader() const;
+  lldb_private::Status DumpDirectories() const;
+  bool CheckIf_64Bit(const size_t size);
   // Add directory of StreamType pointing to the current end of the prepared
   // file with the specified size.
-  void AddDirectory(llvm::minidump::StreamType type, size_t stream_size);
-  size_t GetCurrentDataEndOffset() const;
-
-  // Stores directories to later put them at the end of minidump file
+  void AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size);
+  lldb::addr_t GetCurrentDataEndOffset() const;
+  // Stores directories to fill in later
   std::vector m_directories;
+  // When we write off the threads for the first time, we need to clean them up
+  // and give them the correct RVA once we write the stack memory list.
+  std::map m_thread_by_range_start;

Jlalond wrote:

In this case, the map is the start of the memory range, and the corresponding 
thread. So I think addr_t is more clear. If it is not, I'll take map name 
recommendations.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;

Jlalond wrote:

I responded above on this, I tried to minimize allocating vectors and reduce 
iterations by just removing what will fit in 32b. 

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.
+  Process::CoreFileMemoryRanges ranges;
+  error = process_sp->CalculateCoreFileSaveRanges(core_style, ranges);
+  if (error.Fail()) {
+return error;
+  }
+
+  uint64_t total_size =
+  256 + (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));
+  // Take all the memory that will fit in the 32b range.
+  for (int i = ranges.size() - 1; i >= 0; i--) {

Jlalond wrote:

The reverse is so that I can remove them in place, this was so that I could use 
two lists. The reason being is I already get the stacks in my first call to 
process, and then I call process again with the user specific style. This is so 
stacks are the first items in the memory list for the thread RVA's. 

So I remove anything from the second call to process and instead move it to the 
list of ranges I pass to memorylist, and the remaining go to memorylist64.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-13 Thread Jacob Lalonde via lldb-commits


@@ -40,7 +46,7 @@ lldb_private::Status WriteString(const std::string _write,
 /// the data on heap.
 class MinidumpFileBuilder {
 public:
-  MinidumpFileBuilder() = default;
+  MinidumpFileBuilder(lldb::FileUP&& core_file): 
m_core_file(std::move(core_file)) {};

Jlalond wrote:

I agree with this. I also think it reduces the split responsibility with 
`ObjectfileMinidump`

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+
+  lldb_private::Status AddMemory(const lldb::ProcessSP _sp,
+ lldb::SaveCoreStyle core_style);
+
+  lldb_private::Status DumpToFile();
 
 private:
+  // Add data to the end of the buffer, if the buffer exceeds the flush level,
+  // trigger a flush.
+  lldb_private::Status AddData(const void *data, size_t size);
+  // Add MemoryList stream, containing dumps of important memory segments
+  lldb_private::Status
+  AddMemoryList_64(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status
+  AddMemoryList_32(const lldb::ProcessSP _sp,
+   const lldb_private::Process::CoreFileMemoryRanges );
+  lldb_private::Status FixThreads();
+  lldb_private::Status FlushToDisk();
+
+  lldb_private::Status DumpHeader() const;
+  lldb_private::Status DumpDirectories() const;
+  bool CheckIf_64Bit(const size_t size);
   // Add directory of StreamType pointing to the current end of the prepared
   // file with the specified size.
-  void AddDirectory(llvm::minidump::StreamType type, size_t stream_size);
-  size_t GetCurrentDataEndOffset() const;
-
-  // Stores directories to later put them at the end of minidump file
+  void AddDirectory(llvm::minidump::StreamType type, uint64_t stream_size);
+  lldb::addr_t GetCurrentDataEndOffset() const;

clayborg wrote:

return `lldb::offset_t` instead of `lldb::addr_t`.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);

clayborg wrote:

We know stacks need to go into the `ranges_32` list so this could be:
```
// Thread stacks must use 32 bit memory ranges as that is all that
//  the thread structure allows
 error = process_sp->CalculateCoreFileSaveRanges(
  SaveCoreStyle::eSaveCoreStackOnly, ranges_32);
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.

clayborg wrote:

These 3 lines of comments seem out of place for the code that comes beneath it, 
place closer to the code that enforces this

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);

clayborg wrote:

These haven't changed at all, so I would move them back to this line. No need 
to make changes to this header file if things haven't changed (`AddThreadList` 
and `AddExceptions`). So make as much of this the same as it was before by 
reverting the above 3 lines and removing them from below.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.
+  Process::CoreFileMemoryRanges ranges;
+  error = process_sp->CalculateCoreFileSaveRanges(core_style, ranges);
+  if (error.Fail()) {
+return error;
+  }
+
+  uint64_t total_size =
+  256 + (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));
+  // Take all the memory that will fit in the 32b range.
+  for (int i = ranges.size() - 1; i >= 0; i--) {
+addr_t size_to_add =
+ranges[i].range.size() + sizeof(llvm::minidump::MemoryDescriptor);
+// filter out the stacks and check if it's below 32b max.
+if (stack_ranges.count(ranges[i].range.start()) > 0) {
+  ranges.erase(ranges.begin() + i);
+} else if (total_size + size_to_add < UINT32_MAX) {
+  ranges_for_memory_list.push_back(ranges[i]);
+  total_size += ranges[i].range.size();
+  total_size += sizeof(llvm::minidump::MemoryDescriptor);
+  ranges.erase(ranges.begin() + i);
+} else {
+  break;
+}
+  }
 
+  error = AddMemoryList_32(process_sp, ranges_for_memory_list);
+  if (error.Fail())
+return error;
+
+  // Add the remaining memory as a 64b range.
+  if (ranges.size() > 0) {
+error = AddMemoryList_64(process_sp, ranges);

clayborg wrote:

```
if (!ranges_64.empty()) {
  error = AddMemoryList_64(process_sp, ranges_64);
```


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }

clayborg wrote:

remove `{}` from single line `for` statement and use `ranges_32` and rename 
`stack_ranges` to `stack_start_addresses` since that is what we are storing:
```
std::set stack_start_addresses;
for (const auto _range : ranges_32)
  stack_start_addresses.insert(core_range.range.start());
```
We also need to make sure the current `ranges_32` doesn't exceed 4GB or we must 
error out since the thread stacks must be under 4GB. Or we can avoid fixing the 
stack memory descriptor for any threads that exceed the 4GB barrier

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);
   // Dump the prepared data into file. In case of the failure data are
   // intact.
-  lldb_private::Status Dump(lldb::FileUP _file) const;
-  // Returns the current number of directories(streams) that have been so far
-  // created. This number of directories will be dumped when calling Dump()
-  size_t GetDirectoriesNum() const;
+  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
+

clayborg wrote:

Revert these two lines and use the old ones that were removed above.

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.
+  Process::CoreFileMemoryRanges ranges;
+  error = process_sp->CalculateCoreFileSaveRanges(core_style, ranges);
+  if (error.Fail()) {
+return error;
+  }
+
+  uint64_t total_size =
+  256 + (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));

clayborg wrote:

What is 256 here? And why do we care about `ranges.size() * 
sizeof(llvm::minidump::MemoryDescriptor_64))`?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -59,39 +68,67 @@ class MinidumpFileBuilder {
   // Add ThreadList stream, containing information about all threads running
   // at the moment of core saving. Contains information about thread
   // contexts.
-  lldb_private::Status AddThreadList(const lldb::ProcessSP _sp);
-  // Add Exception streams for any threads that stopped with exceptions.
-  void AddExceptions(const lldb::ProcessSP _sp);
-  // Add MemoryList stream, containing dumps of important memory segments
-  lldb_private::Status AddMemoryList(const lldb::ProcessSP _sp,
- lldb::SaveCoreStyle core_style);
   // Add MiscInfo stream, mainly providing ProcessId
   void AddMiscInfo(const lldb::ProcessSP _sp);
   // Add informative files about a Linux process
   void AddLinuxFileStreams(const lldb::ProcessSP _sp);
+  // Add Exception streams for any threads that stopped with exceptions.
+  void AddExceptions(const lldb::ProcessSP _sp);

clayborg wrote:

Revert to be the same as the lines removed from above to minimize changes to 
this file

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -40,7 +46,7 @@ lldb_private::Status WriteString(const std::string _write,
 /// the data on heap.
 class MinidumpFileBuilder {
 public:
-  MinidumpFileBuilder() = default;
+  MinidumpFileBuilder(lldb::FileUP&& core_file): 
m_core_file(std::move(core_file)) {};

clayborg wrote:

We should a `const lldb::ProcessSP _sp` to the constructor and remove 
all `const lldb::ProcessSP _sp` arguemnts from the methods below. We 
never want to change processes while creating a minidump. We should store the 
process shared pointer as an instance variable and then the methods that used 
to take the `const lldb::ProcessSP _sp` as an argument now use the 
instance variable:
```
  lldb::ProcessSP m_process_sp;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;

clayborg wrote:

It might be useful to create two Process::CoreFileMemoryRanges lists: one for 
32 bit and one for 64 bit and have a variable that keeps track of what was 
already added:
```
uint64_t ranges_32_size = 0;
Process::CoreFileMemoryRanges ranges_32;
Process::CoreFileMemoryRanges ranges_64;
```
Then we can add regions to each list as needed below without having to remove 
anything from the `ranges` list below?

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.
+  Process::CoreFileMemoryRanges ranges;
+  error = process_sp->CalculateCoreFileSaveRanges(core_style, ranges);
+  if (error.Fail()) {
+return error;
+  }
+
+  uint64_t total_size =
+  256 + (ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));
+  // Take all the memory that will fit in the 32b range.
+  for (int i = ranges.size() - 1; i >= 0; i--) {

clayborg wrote:

Why are we iterating over the ranges in reverse order? It might be easier to 
iterate over the ranges in the normal order and then adding the right ranges to 
either the `ranges_32` or `ranges_64` list as needed? So this could be just:
```
for (const auto : all_ranges) {
  lldb::offset_t range_32_size = range.range.size() + 
sizeof(llvm::minidump::MemoryDescriptor);
  if (stack_start_addresses.count(ranges[i].range.start()) > 0)
continue; // Stack range that was already added to range_32
  if (total_size + range_32_size < UINT32_MAX) {
ranges_32.push_back(range);
total_size += range_32_size;
  } else {
ranges_64.push_back(range);
  }
}
```


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits

https://github.com/clayborg requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits


@@ -797,20 +822,75 @@ void MinidumpFileBuilder::AddLinuxFileStreams(
   }
 }
 
-Status MinidumpFileBuilder::Dump(lldb::FileUP _file) const {
-  constexpr size_t header_size = sizeof(llvm::minidump::Header);
-  constexpr size_t directory_size = sizeof(llvm::minidump::Directory);
+Status MinidumpFileBuilder::AddMemory(const ProcessSP _sp,
+  SaveCoreStyle core_style) {
+  Status error;
+
+  Process::CoreFileMemoryRanges ranges_for_memory_list;
+  error = process_sp->CalculateCoreFileSaveRanges(
+  SaveCoreStyle::eSaveCoreStackOnly, ranges_for_memory_list);
+  if (error.Fail()) {
+return error;
+  }
+
+  std::set stack_ranges;
+  for (const auto _range : ranges_for_memory_list) {
+stack_ranges.insert(core_range.range.start());
+  }
+  // We leave a little padding for dictionary and any other metadata we would
+  // want. Also so that we can put the header of the memory list 64 in 32b 
land,
+  // because the directory requires a 32b RVA.
+  Process::CoreFileMemoryRanges ranges;
+  error = process_sp->CalculateCoreFileSaveRanges(core_style, ranges);
+  if (error.Fail()) {
+return error;
+  }

clayborg wrote:

single line if statements should have not `{}`:
```
if (error.Fail())
  return error;
```

https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Greg Clayton via lldb-commits

https://github.com/clayborg edited 
https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread via lldb-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff d6bbe2e20ff21cc2d31106742dfe1711ae5c641e 
c592936dedb0dc494b03144d741ce57ac0b27809 -- 
lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h 
lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp 
llvm/include/llvm/BinaryFormat/Minidump.h 
llvm/lib/ObjectYAML/MinidumpEmitter.cpp
``





View the diff from clang-format here.


``diff
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index 3c1d88652c..ca09e89cd6 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -24,7 +24,6 @@
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
-#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
@@ -311,10 +310,12 @@ Status MinidumpFileBuilder::AddModuleList(Target ) 
{
 auto maybe_mod_size = getModuleFileSize(target, mod);
 if (!maybe_mod_size) {
   llvm::Error mod_size_err = maybe_mod_size.takeError();
-  llvm::handleAllErrors(std::move(mod_size_err), [&](const 
llvm::ErrorInfoBase ) {
-error.SetErrorStringWithFormat("Unable to get the size of module %s: 
%s.",
- module_name.c_str(), E.message().c_str());
-  });
+  llvm::handleAllErrors(std::move(mod_size_err),
+[&](const llvm::ErrorInfoBase ) {
+  error.SetErrorStringWithFormat(
+  "Unable to get the size of module %s: %s.",
+  module_name.c_str(), E.message().c_str());
+});
   return error;
 }
 
@@ -950,10 +951,10 @@ Status MinidumpFileBuilder::AddMemoryList_32(
 const addr_t size = core_range.range.size();
 auto data_up = std::make_unique(size, 0);
 
-LLDB_LOGF(
-log,
-"AddMemoryList %zu/%zu reading memory for region (%zu bytes) [%zx, 
%zx)",
-region_index, ranges.size(), size, addr, addr + size);
+LLDB_LOGF(log,
+  "AddMemoryList %zu/%zu reading memory for region (%zu bytes) "
+  "[%zx, %zx)",
+  region_index, ranges.size(), size, addr, addr + size);
 ++region_index;
 
 const size_t bytes_read =
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
index 178318a2d6..441eef388b 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h
@@ -46,7 +46,8 @@ lldb_private::Status WriteString(const std::string _write,
 /// the data on heap.
 class MinidumpFileBuilder {
 public:
-  MinidumpFileBuilder(lldb::FileUP&& core_file): 
m_core_file(std::move(core_file)) {};
+  MinidumpFileBuilder(lldb::FileUP &_file)
+  : m_core_file(std::move(core_file)) {};
 
   MinidumpFileBuilder(const MinidumpFileBuilder &) = delete;
   MinidumpFileBuilder =(const MinidumpFileBuilder &) = delete;

``




https://github.com/llvm/llvm-project/pull/95312
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread via lldb-commits

llvmbot wrote:




@llvm/pr-subscribers-llvm-binary-utilities

Author: Jacob Lalonde (Jlalond)


Changes

Currently, LLDB does not support taking a minidump over the 4.2gb limit imposed 
by uint32. In fact, currently it writes the RVA's and the headers to the end of 
the file, which can become corrupted due to the header offset only supporting a 
32b offset.

This change reorganizes how the file structure is laid out. LLDB will 
precalculate the number of directories required and preallocate space at the 
top of the file to fill in later. Additionally, thread stacks require a 32b 
offset, and we provision empty descriptors and keep track of them to clean up 
once we write the 32b memory list. 

For 
[MemoryList64](https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_memory64_list),
 the RVA to the start of the section itself will remain in a 32b addressable 
space. We achieve this by predetermining the space the memory regions will 
take, and only writing up to 4.2 gb of data with some buffer to allow all the 
MemoryDescriptor64s to also still be 32b addressable.

I did not add any explicit tests to this PR because allocating 4.2gb+ to test 
is very expensive. However, we have 32b automation tests and I validated with 
in several ways, including with 5gb+ array/object and would be willing to add 
this as a test case.

---

Patch is 36.01 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/95312.diff


5 Files Affected:

- (modified) lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
(+412-118) 
- (modified) lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h 
(+52-15) 
- (modified) lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp 
(+23-25) 
- (modified) llvm/include/llvm/BinaryFormat/Minidump.h (+5) 
- (modified) llvm/lib/ObjectYAML/MinidumpEmitter.cpp (+2) 


``diff
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index 7231433619ffb..3c1d88652cc92 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -20,25 +20,98 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
+#include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories(
+const lldb_private::Target , const lldb::ProcessSP _sp) {
+  // First set the offset on the file, and on the bytes saved
+  m_saved_data_size += header_size;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList
+  // (corresponding memory list for stacks) And an additional memory list for
+  // non-stacks.
+  m_expected_directories = 6;
+  // Check if OS is linux
+  if (target.GetArchitecture().GetTriple().getOS() ==
+  llvm::Triple::OSType::Linux)
+m_expected_directories += 9;
+
+  // Go through all of the threads and check for exceptions.
+  lldb_private::ThreadList thread_list = process_sp->GetThreadList();
+  const uint32_t num_threads = thread_list.GetSize();
+  for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+if (stop_info_sp &&
+stop_info_sp->GetStopReason() == StopReason::eStopReasonException) {
+  m_expected_directories++;
+}
+  }
+
+  // Now offset the file by the directores so we can write them in later.
+  offset_t directory_offset = m_expected_directories * directory_size;
+  m_saved_data_size += directory_offset;
+  // Replace this when we make a better way to do this.
+  Status error;
+  Header empty_header;
+  size_t bytes_written;
+  bytes_written = header_size;
+  error = m_core_file->Write(_header, bytes_written);
+  if (error.Fail() || bytes_written != header_size) {
+if (bytes_written != header_size)
+  error.SetErrorStringWithFormat(
+  "unable to write the header (written %zd/%zd)", bytes_written,
+  header_size);
+return error;
+  }
+
+ 

[Lldb-commits] [lldb] [llvm] [LLDB][Minidump] Add 64b support to LLDB's minidump file builder. (PR #95312)

2024-06-12 Thread Jacob Lalonde via lldb-commits

https://github.com/Jlalond created 
https://github.com/llvm/llvm-project/pull/95312

Currently, LLDB does not support taking a minidump over the 4.2gb limit imposed 
by uint32. In fact, currently it writes the RVA's and the headers to the end of 
the file, which can become corrupted due to the header offset only supporting a 
32b offset.

This change reorganizes how the file structure is laid out. LLDB will 
precalculate the number of directories required and preallocate space at the 
top of the file to fill in later. Additionally, thread stacks require a 32b 
offset, and we provision empty descriptors and keep track of them to clean up 
once we write the 32b memory list. 

For 
[MemoryList64](https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_memory64_list),
 the RVA to the start of the section itself will remain in a 32b addressable 
space. We achieve this by predetermining the space the memory regions will 
take, and only writing up to 4.2 gb of data with some buffer to allow all the 
MemoryDescriptor64s to also still be 32b addressable.

I did not add any explicit tests to this PR because allocating 4.2gb+ to test 
is very expensive. However, we have 32b automation tests and I validated with 
in several ways, including with 5gb+ array/object and would be willing to add 
this as a test case.

>From 810865580a4d8ea3f48e56f3964602fba6087ddf Mon Sep 17 00:00:00 2001
From: Jacob Lalonde 
Date: Wed, 12 Jun 2024 13:57:10 -0700
Subject: [PATCH 1/5] Squash minidump-64-protoype.

This is a change to reorder LLDB's minidumps to support 64b memory 
lists/minidumps while still keeping all directories under the 32b limit.

Better O(N), not N^2 cleanup code
---
 .../Minidump/MinidumpFileBuilder.cpp  | 520 ++
 .../ObjectFile/Minidump/MinidumpFileBuilder.h |  55 +-
 .../Minidump/ObjectFileMinidump.cpp   |  38 +-
 llvm/include/llvm/BinaryFormat/Minidump.h |  11 +
 llvm/include/llvm/Object/Minidump.h   |   7 +
 llvm/lib/ObjectYAML/MinidumpEmitter.cpp   |   7 +
 6 files changed, 482 insertions(+), 156 deletions(-)

diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp 
b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index 7231433619ffb..c08b5206720ab 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -20,35 +20,106 @@
 #include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/StopInfo.h"
 #include "lldb/Target/ThreadList.h"
+#include "lldb/Utility/DataBufferHeap.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/RegisterValue.h"
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/BinaryFormat/Minidump.h"
 #include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 
 #include "Plugins/Process/minidump/MinidumpTypes.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
 
 using namespace lldb;
 using namespace lldb_private;
 using namespace llvm::minidump;
 
-void MinidumpFileBuilder::AddDirectory(StreamType type, size_t stream_size) {
+Status MinidumpFileBuilder::AddHeaderAndCalculateDirectories(const 
lldb_private::Target , const lldb::ProcessSP _sp) {
+  // First set the offset on the file, and on the bytes saved
+  //TODO: advance the core file.
+  m_saved_data_size += header_size;
+  // We know we will have at least Misc, SystemInfo, Modules, and ThreadList 
(corresponding memory list for stacks)
+  // And an additional memory list for non-stacks.
+  m_expected_directories = 6;
+  // Check if OS is linux
+  if (target.GetArchitecture().GetTriple().getOS() ==
+  llvm::Triple::OSType::Linux)
+m_expected_directories += 9;
+
+  // Go through all of the threads and check for exceptions.
+  lldb_private::ThreadList thread_list = process_sp->GetThreadList();
+  const uint32_t num_threads = thread_list.GetSize();
+  for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
+ThreadSP thread_sp(thread_list.GetThreadAtIndex(thread_idx));
+StopInfoSP stop_info_sp = thread_sp->GetStopInfo();
+if (stop_info_sp && stop_info_sp->GetStopReason() == 
StopReason::eStopReasonException) {
+  m_expected_directories++;
+}
+  }
+
+  // Now offset the file by the directores so we can write them in later.
+  offset_t directory_offset = m_expected_directories * directory_size;
+  //TODO: advance the core file.
+  m_saved_data_size += directory_offset;
+  // Replace this when we make a better way to do this.
+  Status error;
+  Header empty_header;
+  size_t bytes_written;
+  bytes_written = header_size;
+  error = m_core_file->Write(_header, bytes_written);
+  if (error.Fail() || bytes_written !=