forked from OSchip/llvm-project
Add the ability to append breakpoints to the save file.
llvm-svn: 282212
This commit is contained in:
parent
be0ed59cdc
commit
2d3628e1f0
|
@ -703,11 +703,17 @@ public:
|
|||
/// @param[in] bkpt_list
|
||||
/// Only write breakpoints from this list.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If \btrue, append the breakpoints in bkpt_list to the others
|
||||
/// serialized in dest_file. If dest_file doesn't exist, then a new
|
||||
/// file will be created and the breakpoints in bkpt_list written to it.
|
||||
///
|
||||
/// @return
|
||||
/// An SBError detailing any errors in writing in the breakpoints.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBError BreakpointsWriteToFile(SBFileSpec &dest_file,
|
||||
SBBreakpointList &bkpt_list);
|
||||
SBBreakpointList &bkpt_list,
|
||||
bool append = false);
|
||||
|
||||
uint32_t GetNumBreakpoints() const;
|
||||
|
||||
|
|
|
@ -679,7 +679,7 @@ public:
|
|||
bool IgnoreWatchpointByID(lldb::watch_id_t watch_id, uint32_t ignore_count);
|
||||
|
||||
Error SerializeBreakpointsToFile(const FileSpec &file,
|
||||
const BreakpointIDList &bp_ids);
|
||||
const BreakpointIDList &bp_ids, bool append);
|
||||
|
||||
Error CreateBreakpointsFromFile(const FileSpec &file,
|
||||
BreakpointIDList &new_bps);
|
||||
|
|
|
@ -37,6 +37,12 @@ class BreakpointSerialization(TestBase):
|
|||
self.setup_targets_and_cleanup()
|
||||
self.do_check_options()
|
||||
|
||||
def test_appending(self):
|
||||
"""Use Python APIs to test that we serialize breakpoint options correctly."""
|
||||
self.build()
|
||||
self.setup_targets_and_cleanup()
|
||||
self.do_check_appending()
|
||||
|
||||
def test_name_filters(self):
|
||||
"""Use python APIs to test that reading in by name works correctly."""
|
||||
self.build()
|
||||
|
@ -70,11 +76,13 @@ class BreakpointSerialization(TestBase):
|
|||
self.bkpts_file_path = os.path.join(os.getcwd(), "breakpoints.json")
|
||||
self.bkpts_file_spec = lldb.SBFileSpec(self.bkpts_file_path)
|
||||
|
||||
def check_equivalence(self, source_bps):
|
||||
def check_equivalence(self, source_bps, do_write = True):
|
||||
|
||||
error = lldb.SBError()
|
||||
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
|
||||
self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
|
||||
|
||||
if (do_write):
|
||||
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
|
||||
self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
|
||||
|
||||
copy_bps = lldb.SBBreakpointList(self.copy_target)
|
||||
error = self.copy_target.BreakpointsCreateFromFile(self.bkpts_file_spec, copy_bps)
|
||||
|
@ -205,6 +213,52 @@ class BreakpointSerialization(TestBase):
|
|||
|
||||
self.check_equivalence(source_bps)
|
||||
|
||||
def do_check_appending(self):
|
||||
"""Use Python APIs to check appending to already serialized options."""
|
||||
|
||||
empty_module_list = lldb.SBFileSpecList()
|
||||
empty_cu_list = lldb.SBFileSpecList()
|
||||
blubby_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "blubby.c"))
|
||||
|
||||
# It isn't actually important for these purposes that these breakpoint
|
||||
# actually have locations.
|
||||
|
||||
all_bps = lldb.SBBreakpointList(self.orig_target)
|
||||
source_bps = lldb.SBBreakpointList(self.orig_target)
|
||||
|
||||
bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666)
|
||||
bkpt.SetEnabled(False)
|
||||
bkpt.SetOneShot(True)
|
||||
bkpt.SetThreadID(10)
|
||||
source_bps.Append(bkpt)
|
||||
all_bps.Append(bkpt)
|
||||
|
||||
error = lldb.SBError()
|
||||
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps)
|
||||
self.assertTrue(error.Success(), "Failed writing breakpoints to file: %s."%(error.GetCString()))
|
||||
|
||||
source_bps.Clear()
|
||||
|
||||
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeAuto, empty_module_list, empty_cu_list)
|
||||
bkpt.SetIgnoreCount(10)
|
||||
bkpt.SetThreadName("grubby")
|
||||
source_bps.Append(bkpt)
|
||||
all_bps.Append(bkpt)
|
||||
|
||||
bkpt = self.orig_target.BreakpointCreateByName("blubby", lldb.eFunctionNameTypeFull, empty_module_list,empty_cu_list)
|
||||
bkpt.SetCondition("something != something_else")
|
||||
bkpt.SetQueueName("grubby")
|
||||
bkpt.AddName("FirstName")
|
||||
bkpt.AddName("SecondName")
|
||||
|
||||
source_bps.Append(bkpt)
|
||||
all_bps.Append(bkpt)
|
||||
|
||||
error = self.orig_target.BreakpointsWriteToFile(self.bkpts_file_spec, source_bps, True)
|
||||
self.assertTrue(error.Success(), "Failed appending breakpoints to file: %s."%(error.GetCString()))
|
||||
|
||||
self.check_equivalence(all_bps)
|
||||
|
||||
def do_check_names(self):
|
||||
bkpt = self.orig_target.BreakpointCreateByLocation("blubby.c", 666)
|
||||
good_bkpt_name = "GoodBreakpoint"
|
||||
|
|
|
@ -786,12 +786,19 @@ public:
|
|||
/// @param[in] bkpt_list
|
||||
/// Only write breakpoints from this list.
|
||||
///
|
||||
/// @param[in] append
|
||||
/// If \btrue, append the breakpoints in bkpt_list to the others
|
||||
/// serialized in dest_file. If dest_file doesn't exist, then a new
|
||||
/// file will be created and the breakpoints in bkpt_list written to it.
|
||||
///
|
||||
/// @return
|
||||
/// An SBError detailing any errors in writing in the breakpoints.
|
||||
//------------------------------------------------------------------
|
||||
") BreakpointsCreateFromFile;
|
||||
lldb::SBError
|
||||
BreakpointsWriteToFile(SBFileSpec &dest_file, SBBreakpointList &bkpt_list);
|
||||
BreakpointsWriteToFile(SBFileSpec &dest_file,
|
||||
SBBreakpointList &bkpt_list,
|
||||
bool append = false);
|
||||
|
||||
uint32_t
|
||||
GetNumWatchpoints () const;
|
||||
|
|
|
@ -1176,7 +1176,8 @@ lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file) {
|
|||
}
|
||||
|
||||
lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file,
|
||||
SBBreakpointList &bkpt_list) {
|
||||
SBBreakpointList &bkpt_list,
|
||||
bool append) {
|
||||
SBError sberr;
|
||||
TargetSP target_sp(GetSP());
|
||||
if (!target_sp) {
|
||||
|
@ -1187,8 +1188,8 @@ lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file,
|
|||
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
|
||||
BreakpointIDList bp_id_list;
|
||||
bkpt_list.CopyToBreakpointIDList(bp_id_list);
|
||||
sberr.ref() =
|
||||
target_sp->SerializeBreakpointsToFile(dest_file.ref(), bp_id_list);
|
||||
sberr.ref() = target_sp->SerializeBreakpointsToFile(dest_file.ref(),
|
||||
bp_id_list, append);
|
||||
return sberr;
|
||||
}
|
||||
|
||||
|
|
|
@ -2210,7 +2210,8 @@ private:
|
|||
#pragma mark Write::CommandOptions
|
||||
static OptionDefinition g_breakpoint_write_options[] = {
|
||||
// clang-format off
|
||||
{ LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
|
||||
{ LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." },
|
||||
{ LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."},
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
@ -2251,6 +2252,9 @@ public:
|
|||
case 'f':
|
||||
m_filename.assign(option_arg);
|
||||
break;
|
||||
case 'a':
|
||||
m_append = true;
|
||||
break;
|
||||
default:
|
||||
error.SetErrorStringWithFormat("unrecognized option '%c'",
|
||||
short_option);
|
||||
|
@ -2262,6 +2266,7 @@ public:
|
|||
|
||||
void OptionParsingStarting(ExecutionContext *execution_context) override {
|
||||
m_filename.clear();
|
||||
m_append = false;
|
||||
}
|
||||
|
||||
llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
|
||||
|
@ -2271,6 +2276,7 @@ public:
|
|||
// Instance variables to hold the values for command options.
|
||||
|
||||
std::string m_filename;
|
||||
bool m_append = false;
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -2296,7 +2302,8 @@ protected:
|
|||
}
|
||||
}
|
||||
Error error = target->SerializeBreakpointsToFile(
|
||||
FileSpec(m_options.m_filename.c_str(), true), valid_bp_ids);
|
||||
FileSpec(m_options.m_filename.c_str(), true), valid_bp_ids,
|
||||
m_options.m_append);
|
||||
if (!error.Success()) {
|
||||
result.AppendErrorWithFormat("error serializing breakpoints: %s.",
|
||||
error.AsCString());
|
||||
|
|
|
@ -796,7 +796,8 @@ bool Target::EnableBreakpointByID(break_id_t break_id) {
|
|||
}
|
||||
|
||||
Error Target::SerializeBreakpointsToFile(const FileSpec &file,
|
||||
const BreakpointIDList &bp_ids) {
|
||||
const BreakpointIDList &bp_ids,
|
||||
bool append) {
|
||||
Error error;
|
||||
|
||||
if (!file) {
|
||||
|
@ -805,6 +806,28 @@ Error Target::SerializeBreakpointsToFile(const FileSpec &file,
|
|||
}
|
||||
|
||||
std::string path(file.GetPath());
|
||||
StructuredData::ObjectSP input_data_sp;
|
||||
|
||||
StructuredData::ArraySP break_store_sp;
|
||||
StructuredData::Array *break_store_ptr = nullptr;
|
||||
|
||||
if (append) {
|
||||
input_data_sp = StructuredData::ParseJSONFromFile(file, error);
|
||||
if (error.Success()) {
|
||||
break_store_ptr = input_data_sp->GetAsArray();
|
||||
if (!break_store_ptr) {
|
||||
error.SetErrorStringWithFormat(
|
||||
"Tried to append to invalid input file %s", path.c_str());
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!break_store_ptr) {
|
||||
break_store_sp.reset(new StructuredData::Array());
|
||||
break_store_ptr = break_store_sp.get();
|
||||
}
|
||||
|
||||
StreamFile out_file(path.c_str(),
|
||||
File::OpenOptions::eOpenOptionTruncate |
|
||||
File::OpenOptions::eOpenOptionWrite |
|
||||
|
@ -820,7 +843,6 @@ Error Target::SerializeBreakpointsToFile(const FileSpec &file,
|
|||
std::unique_lock<std::recursive_mutex> lock;
|
||||
GetBreakpointList().GetListMutex(lock);
|
||||
|
||||
StructuredData::ArraySP break_store_sp(new StructuredData::Array());
|
||||
if (bp_ids.GetSize() == 0) {
|
||||
const BreakpointList &breakpoints = GetBreakpointList();
|
||||
|
||||
|
@ -830,7 +852,7 @@ Error Target::SerializeBreakpointsToFile(const FileSpec &file,
|
|||
StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
|
||||
// If a breakpoint can't serialize it, just ignore it for now:
|
||||
if (bkpt_save_sp)
|
||||
break_store_sp->AddItem(bkpt_save_sp);
|
||||
break_store_ptr->AddItem(bkpt_save_sp);
|
||||
}
|
||||
} else {
|
||||
|
||||
|
@ -857,12 +879,12 @@ Error Target::SerializeBreakpointsToFile(const FileSpec &file,
|
|||
bp_id);
|
||||
return error;
|
||||
}
|
||||
break_store_sp->AddItem(bkpt_save_sp);
|
||||
break_store_ptr->AddItem(bkpt_save_sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break_store_sp->Dump(out_file, false);
|
||||
break_store_ptr->Dump(out_file, false);
|
||||
out_file.PutChar('\n');
|
||||
return error;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue