Skip to content

Commit 661382f

Browse files
authored
[LLDB][Minidump] Minidump erase file on failure (#108259)
In #95312 Minidump file creation was moved from being created at the end, to the file being emitted in chunks. This causes some undesirable behavior where the file can still be present after an error has occurred. To resolve this we will now delete the file upon an error.
1 parent cd6844c commit 661382f

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,3 +1218,15 @@ Status MinidumpFileBuilder::DumpFile() {
12181218

12191219
return error;
12201220
}
1221+
1222+
void MinidumpFileBuilder::DeleteFile() noexcept {
1223+
Log *log = GetLog(LLDBLog::Object);
1224+
1225+
if (m_core_file) {
1226+
Status error = m_core_file->Close();
1227+
if (error.Fail())
1228+
LLDB_LOGF(log, "Failed to close minidump file: %s", error.AsCString());
1229+
1230+
m_core_file.reset();
1231+
}
1232+
}

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ class MinidumpFileBuilder {
115115
// Run cleanup and write all remaining bytes to file
116116
lldb_private::Status DumpFile();
117117

118+
// Delete the file if it exists
119+
void DeleteFile() noexcept;
120+
118121
private:
119122
// Add data to the end of the buffer, if the buffer exceeds the flush level,
120123
// trigger a flush.

lldb/source/Plugins/ObjectFile/Minidump/ObjectFileMinidump.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ size_t ObjectFileMinidump::GetModuleSpecifications(
5555
return 0;
5656
}
5757

58+
struct DumpFailRemoveHolder {
59+
DumpFailRemoveHolder(MinidumpFileBuilder &builder) : m_builder(builder) {}
60+
61+
~DumpFailRemoveHolder() {
62+
if (!m_success)
63+
m_builder.DeleteFile();
64+
}
65+
66+
void SetSuccess() { m_success = true; }
67+
68+
private:
69+
MinidumpFileBuilder &m_builder;
70+
bool m_success = false;
71+
};
72+
5873
bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
5974
lldb_private::SaveCoreOptions &options,
6075
lldb_private::Status &error) {
@@ -75,6 +90,7 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
7590
}
7691
MinidumpFileBuilder builder(std::move(maybe_core_file.get()), process_sp,
7792
options);
93+
DumpFailRemoveHolder request(builder);
7894

7995
Log *log = GetLog(LLDBLog::Object);
8096
error = builder.AddHeaderAndCalculateDirectories();
@@ -133,5 +149,7 @@ bool ObjectFileMinidump::SaveCore(const lldb::ProcessSP &process_sp,
133149
return false;
134150
}
135151

152+
request.SetSuccess();
153+
136154
return true;
137155
}

lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidump.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,3 +493,32 @@ def test_save_minidump_custom_save_style_duplicated_regions(self):
493493

494494
finally:
495495
self.assertTrue(self.dbg.DeleteTarget(target))
496+
497+
@skipUnlessPlatform(["linux"])
498+
def minidump_deleted_on_save_failure(self):
499+
"""Test that verifies the minidump file is deleted after an error"""
500+
501+
self.build()
502+
exe = self.getBuildArtifact("a.out")
503+
try:
504+
target = self.dbg.CreateTarget(exe)
505+
process = target.LaunchSimple(
506+
None, None, self.get_process_working_directory()
507+
)
508+
self.assertState(process.GetState(), lldb.eStateStopped)
509+
510+
custom_file = self.getBuildArtifact("core.should.be.deleted.custom.dmp")
511+
options = lldb.SBSaveCoreOptions()
512+
options.SetOutputFile(lldb.SBFileSpec(custom_file))
513+
options.SetPluginName("minidump")
514+
options.SetStyle(lldb.eSaveCoreCustomOnly)
515+
# We set custom only and have no thread list and have no memory.
516+
error = process.SaveCore(options)
517+
self.assertTrue(error.Fail())
518+
self.assertIn(
519+
"no valid address ranges found for core style", error.GetCString()
520+
)
521+
self.assertTrue(not os.path.isfile(custom_file))
522+
523+
finally:
524+
self.assertTrue(self.dbg.DeleteTarget(target))

0 commit comments

Comments
 (0)