summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/Target.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Target/Target.cpp')
-rw-r--r--lldb/source/Target/Target.cpp122
1 files changed, 122 insertions, 0 deletions
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index bd8ae563319..0b612c6ddae 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -15,6 +15,7 @@
#include "Plugins/ExpressionParser/Clang/ClangASTSource.h"
#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
+#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverAddress.h"
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
@@ -794,6 +795,127 @@ bool Target::EnableBreakpointByID(break_id_t break_id) {
return false;
}
+Error Target::SerializeBreakpointsToFile(const FileSpec &file,
+ const BreakpointIDList &bp_ids) {
+ Error error;
+
+ if (!file) {
+ error.SetErrorString("Invalid FileSpec.");
+ return error;
+ }
+
+ std::string path(file.GetPath());
+ StreamFile out_file(path.c_str(),
+ File::OpenOptions::eOpenOptionTruncate |
+ File::OpenOptions::eOpenOptionWrite |
+ File::OpenOptions::eOpenOptionCanCreate |
+ File::OpenOptions::eOpenOptionCloseOnExec,
+ lldb::eFilePermissionsFileDefault);
+ if (!out_file.GetFile().IsValid()) {
+ error.SetErrorStringWithFormat("Unable to open output file: %s.",
+ path.c_str());
+ return error;
+ }
+
+ 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();
+
+ size_t num_breakpoints = breakpoints.GetSize();
+ for (size_t i = 0; i < num_breakpoints; i++) {
+ Breakpoint *bp = breakpoints.GetBreakpointAtIndex(i).get();
+ 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);
+ }
+ } else {
+
+ std::unordered_set<lldb::break_id_t> processed_bkpts;
+ const size_t count = bp_ids.GetSize();
+ for (size_t i = 0; i < count; ++i) {
+ BreakpointID cur_bp_id = bp_ids.GetBreakpointIDAtIndex(i);
+ lldb::break_id_t bp_id = cur_bp_id.GetBreakpointID();
+
+ if (bp_id != LLDB_INVALID_BREAK_ID) {
+ // Only do each breakpoint once:
+ std::pair<std::unordered_set<lldb::break_id_t>::iterator, bool>
+ insert_result = processed_bkpts.insert(bp_id);
+ if (!insert_result.second)
+ continue;
+
+ Breakpoint *bp = GetBreakpointByID(bp_id).get();
+ StructuredData::ObjectSP bkpt_save_sp = bp->SerializeToStructuredData();
+ // If the user explicitly asked to serialize a breakpoint, and we
+ // can't, then
+ // raise an error:
+ if (!bkpt_save_sp) {
+ error.SetErrorStringWithFormat("Unable to serialize breakpoint %d",
+ bp_id);
+ return error;
+ }
+ break_store_sp->AddItem(bkpt_save_sp);
+ }
+ }
+ }
+
+ break_store_sp->Dump(out_file, false);
+ out_file.PutChar('\n');
+ return error;
+}
+
+Error Target::CreateBreakpointsFromFile(const FileSpec &file,
+ BreakpointIDList &new_bps) {
+ std::unique_lock<std::recursive_mutex> lock;
+ GetBreakpointList().GetListMutex(lock);
+
+ Error error;
+ StructuredData::ObjectSP input_data_sp =
+ StructuredData::ParseJSONFromFile(file, error);
+ if (!error.Success()) {
+ return error;
+ } else if (!input_data_sp || !input_data_sp->IsValid()) {
+ error.SetErrorStringWithFormat("Invalid JSON from input file: %s.",
+ file.GetPath().c_str());
+ return error;
+ }
+
+ StructuredData::Array *bkpt_array = input_data_sp->GetAsArray();
+ if (!bkpt_array) {
+ error.SetErrorStringWithFormat(
+ "Invalid breakpoint data from input file: %s.", file.GetPath().c_str());
+ return error;
+ }
+
+ size_t num_bkpts = bkpt_array->GetSize();
+ for (size_t i = 0; i < num_bkpts; i++) {
+ StructuredData::ObjectSP bkpt_object_sp = bkpt_array->GetItemAtIndex(i);
+ // Peel off the breakpoint key, and feed the rest to the Breakpoint:
+ StructuredData::Dictionary *bkpt_dict = bkpt_object_sp->GetAsDictionary();
+ if (!bkpt_dict) {
+ error.SetErrorStringWithFormat(
+ "Invalid breakpoint data for element %zu from input file: %s.", i,
+ file.GetPath().c_str());
+ return error;
+ }
+ StructuredData::ObjectSP bkpt_data_sp =
+ bkpt_dict->GetValueForKey(Breakpoint::GetSerializationKey());
+ BreakpointSP bkpt_sp =
+ Breakpoint::CreateFromStructuredData(*this, bkpt_data_sp, error);
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat(
+ "Error restoring breakpoint %zu from %s: %s.", i,
+ file.GetPath().c_str(), error.AsCString());
+ return error;
+ }
+ new_bps.AddBreakpointID(BreakpointID(bkpt_sp->GetID()));
+ }
+ return error;
+}
+
// The flag 'end_to_end', default to true, signifies that the operation is
// performed end to end, for both the debugger and the debuggee.
OpenPOWER on IntegriCloud