SBTarget SBDebugger::CreateTarget (const char *filename) { SBTarget target; if (m_opaque_sp) { FileSpec file (filename, true); ArchSpec arch = Target::GetDefaultArchitecture (); TargetSP target_sp; Error error; const bool add_dependent_modules = true; error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, add_dependent_modules, m_opaque_sp->GetPlatformList().GetSelectedPlatform(), target_sp); if (error.Success()) { m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); target.reset (target_sp); } } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", m_opaque_sp.get(), filename, target.get()); } return target; }
SBTarget SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBTarget target; if (m_opaque_sp) { FileSpec file (filename, true); TargetSP target_sp; Error error; const bool add_dependent_modules = true; error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch_cstr, add_dependent_modules, NULL, target_sp); if (error.Success()) { m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get()); target.reset(target_sp); } } if (log) { log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)", m_opaque_sp.get(), filename, arch_cstr, target.get()); } return target; }
void SBWorkspace::queueTargets(const StringSet& targetNames, const StringSet& configNames) { BuildSettings bs(NULL); bool isInteractive = bs.getValue("VSIMPORTER_INTERACTIVE") == "YES"; // Get the specified targets PotentialTargetsVec selectedTargets; if (isInteractive) { // Query the user to select targets to be queued selectTargets(selectedTargets); } else if (targetNames.empty()) { // Queue up all targets getAllTargets(selectedTargets); } else { // Try to find matching targets by name for (auto targetName : targetNames) { TargetProjectPair targetKV = findTargetWithName(targetName); if (targetKV.first) { selectedTargets.push_back(targetKV); } } } // Queue targets for (auto targetKV : selectedTargets) { SBTarget* target = targetKV.second->queueTarget(targetKV.first, &configNames); // Mark target as having been explicitly queued up if (target) { target->markExplicit(); } } }
SBTarget SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename, const char *target_triple) { SBTarget target; if (m_opaque_sp) { FileSpec file_spec (filename, true); TargetSP target_sp; const bool add_dependent_modules = true; Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, target_triple, add_dependent_modules, NULL, target_sp)); target.reset (target_sp); } LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)", m_opaque_sp.get(), filename, target_triple, target.get()); } return target; }
SBBreakpointNameImpl::SBBreakpointNameImpl(SBTarget &sb_target, const char *name) { if (!name || name[0] == '\0') return; m_name.assign(name); if (!sb_target.IsValid()) return; TargetSP target_sp = sb_target.GetSP(); if (!target_sp) return; m_target_wp = target_sp; }
SBValueList SBModule::FindGlobalVariables (SBTarget &target, const char *name, uint32_t max_matches) { SBValueList sb_value_list; ModuleSP module_sp (GetSP ()); if (name && module_sp) { VariableList variable_list; const uint32_t match_count = module_sp->FindGlobalVariables (ConstString (name), NULL, false, max_matches, variable_list); if (match_count > 0) { for (uint32_t i=0; i<match_count; ++i) { lldb::ValueObjectSP valobj_sp; TargetSP target_sp (target.GetSP()); valobj_sp = ValueObjectVariable::Create (target_sp.get(), variable_list.GetVariableAtIndex(i)); if (valobj_sp) sb_value_list.Append(SBValue(valobj_sp)); } } } return sb_value_list; }
lldb::addr_t SBAddress::GetLoadAddress (const SBTarget &target) const { Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); lldb::addr_t addr = LLDB_INVALID_ADDRESS; TargetSP target_sp (target.GetSP()); if (target_sp) { if (m_opaque_ap->IsValid()) { Mutex::Locker api_locker (target_sp->GetAPIMutex()); addr = m_opaque_ap->GetLoadAddress (target_sp.get()); } } if (log) { if (addr == LLDB_INVALID_ADDRESS) log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => LLDB_INVALID_ADDRESS", static_cast<void*>(target_sp.get())); else log->Printf ("SBAddress::GetLoadAddress (SBTarget(%p)) => 0x%" PRIx64, static_cast<void*>(target_sp.get()), addr); } return addr; }
SBInstructionList SBFunction::GetInstructions (SBTarget target, const char *flavor) { SBInstructionList sb_instructions; if (m_opaque_ptr) { Mutex::Locker api_locker; ExecutionContext exe_ctx; TargetSP target_sp (target.GetSP()); if (target_sp) { api_locker.Lock (target_sp->GetAPIMutex()); target_sp->CalculateExecutionContext (exe_ctx); exe_ctx.SetProcessSP(target_sp->GetProcessSP()); } ModuleSP module_sp (m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule()); if (module_sp) { const bool prefer_file_cache = false; sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture(), NULL, flavor, exe_ctx, m_opaque_ptr->GetAddressRange(), prefer_file_cache)); } } return sb_instructions; }
SBInstructionList SBSymbol::GetInstructions(SBTarget target, const char *flavor_string) { SBInstructionList sb_instructions; if (m_opaque_ptr) { ExecutionContext exe_ctx; TargetSP target_sp(target.GetSP()); std::unique_lock<std::recursive_mutex> lock; if (target_sp) { lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); target_sp->CalculateExecutionContext(exe_ctx); } if (m_opaque_ptr->ValueIsAddress()) { const Address &symbol_addr = m_opaque_ptr->GetAddressRef(); ModuleSP module_sp = symbol_addr.GetModule(); if (module_sp) { AddressRange symbol_range(symbol_addr, m_opaque_ptr->GetByteSize()); const bool prefer_file_cache = false; sb_instructions.SetDisassembler(Disassembler::DisassembleRange( module_sp->GetArchitecture(), NULL, flavor_string, exe_ctx, symbol_range, prefer_file_cache)); } } } return sb_instructions; }
void SBDebugger::SetSelectedTarget (SBTarget &sb_target) { LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (m_opaque_sp) { m_opaque_sp->GetTargetList().SetSelectedTarget (sb_target.get()); } if (log) { SBStream sstr; sb_target.GetDescription (sstr, eDescriptionLevelBrief); log->Printf ("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(), sb_target.get(), sstr.GetData()); } }
void Xcode::FetchModules (SBTarget target, bool verbose) { auto count = target.GetNumModules(); for (int i = 0; i < count; i++) { SBModule module(target.GetModuleAtIndex(i)); auto fspec = module.GetFileSpec(); std::string path(1024,0); fspec.GetPath(&path[0],1024); auto uuid = module.GetUUIDBytes(); if (verbose) { printf("%s %s\n",path.c_str(),module.GetUUIDString()); } } }
void test(SBDebugger &dbg, vector<string> args) { SBTarget target = dbg.CreateTarget(args.at(0).c_str()); if (!target.IsValid()) throw Exception("invalid target"); SBBreakpoint breakpoint = target.BreakpointCreateByName("next"); if (!breakpoint.IsValid()) throw Exception("invalid breakpoint"); breakpoint.SetCallback(BPCallback, 0); std::unique_ptr<char> working_dir(get_working_dir()); SBProcess process = target.LaunchSimple (0, 0, working_dir.get()); { unique_lock<mutex> lock(g_mutex); g_condition.wait_for(lock, chrono::seconds(5)); if (g_breakpoint_hit_count != 1) throw Exception("Breakpoint hit count expected to be 1"); } }
lldb::SBTarget SBValue::GetTarget() { SBTarget result; if (m_opaque_sp) { if (m_opaque_sp->GetUpdatePoint().GetTargetSP()) { result = SBTarget(lldb::TargetSP(m_opaque_sp->GetUpdatePoint().GetTargetSP())); } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) { if (result.get() == NULL) log->Printf ("SBValue(%p)::GetTarget () => NULL", m_opaque_sp.get()); else log->Printf ("SBValue(%p)::GetTarget () => %p", m_opaque_sp.get(), result.get()); } return result; }
void SBWorkspace::queueSchemes(const StringSet& schemeNames, const StringSet& configNames) { BuildSettings bs(NULL); bool isInteractive = bs.getValue("VSIMPORTER_INTERACTIVE") == "YES"; // Get the specified schemes SchemeVec schemePtrs; if (schemeNames.empty()) { // Queue up all schemes schemePtrs.insert(schemePtrs.end(), m_schemes.begin(), m_schemes.end()); } else { getSchemes(schemeNames, schemePtrs); } // Process all schemes for (auto scheme : schemePtrs) { // Process all build references in the scheme for (auto buildRef : scheme->getTargets()) { // Construct a path to the project specified by the BuildRef String projectPath = joinPaths(scheme->getContainerParentDir(), buildRef.container); // Find or create the project SBProject* targetProj = openProject(projectPath); // Create the target SBTarget* target = NULL; if (targetProj) { target = targetProj->queueTargetWithId(buildRef.id, &configNames); } else { SBLog::warning() << "Failed to open \"" << buildRef.container << "\" project referenced by \"" << scheme->getName() << "\" scheme. " << "Ignoring \"" << buildRef.targetName << "\" target." << std::endl; } // Mark target as having been explicitly queued up if (target) { target->markExplicit(); } } } }
SBInstructionList SBFunction::GetInstructions (SBTarget target) { SBInstructionList sb_instructions; if (m_opaque_ptr) { Mutex::Locker api_locker; ExecutionContext exe_ctx; if (target.IsValid()) { api_locker.Reset (target->GetAPIMutex().GetMutex()); target->CalculateExecutionContext (exe_ctx); exe_ctx.process = target->GetProcessSP().get(); } Module *module = m_opaque_ptr->GetAddressRange().GetBaseAddress().GetModule(); if (module) { sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module->GetArchitecture(), exe_ctx, m_opaque_ptr->GetAddressRange())); } } return sb_instructions; }
int main (int argc, char const *argv[]) { // Use a sentry object to properly initialize/terminate LLDB. LLDBSentry sentry; SBDebugger debugger (SBDebugger::Create()); // Create a debugger instance so we can create a target if (!debugger.IsValid()) fprintf (stderr, "error: failed to create a debugger object\n"); bool show_usage = false; bool verbose = false; bool canonical = false; bool external_only = false; const char *arch = NULL; const char *platform = NULL; std::string short_options("h?"); for (const struct option *opt = g_long_options; opt->name; ++opt) { if (isprint(opt->val)) { short_options.append(1, (char)opt->val); switch (opt->has_arg) { case no_argument: break; case required_argument: short_options.append(1, ':'); break; case optional_argument: short_options.append(2, ':'); break; } } } #ifdef __GLIBC__ optind = 0; #else optreset = 1; optind = 1; #endif char ch; while ((ch = getopt_long_only(argc, (char * const *)argv, short_options.c_str(), g_long_options, 0)) != -1) { switch (ch) { case 0: break; case 'a': if (arch != NULL) { fprintf (stderr, "error: the --arch option can only be specified once\n"); exit(1); } arch = optarg; break; case 'c': canonical = true; break; case 'x': external_only = true; break; case 'p': platform = optarg; break; case 'v': verbose = true; break; case 'h': case '?': default: show_usage = true; break; } } argc -= optind; argv += optind; const bool add_dependent_libs = false; SBError error; for (int arg_idx = 0; arg_idx < argc; ++arg_idx) { // The first argument is the file path we want to look something up in const char *exe_file_path = argv[arg_idx]; // Create a target using the executable. SBTarget target = debugger.CreateTarget (exe_file_path, arch, platform, add_dependent_libs, error); if (error.Success()) { if (target.IsValid()) { SBFileSpec exe_file_spec (exe_file_path, true); SBModule module (target.FindModule (exe_file_spec)); SBFileSpecList comp_unit_list; if (module.IsValid()) { char command[1024]; lldb::SBCommandReturnObject command_result; snprintf (command, sizeof(command), "add-dsym --uuid %s", module.GetUUIDString()); debugger.GetCommandInterpreter().HandleCommand (command, command_result); if (!command_result.Succeeded()) { fprintf (stderr, "error: couldn't locate debug symbols for '%s'\n", exe_file_path); exit(1); } SBFileSpecList module_list; module_list.Append(exe_file_spec); SBBreakpoint bp = target.BreakpointCreateByRegex (".", module_list, comp_unit_list); const size_t num_locations = bp.GetNumLocations(); for (uint32_t bp_loc_idx=0; bp_loc_idx<num_locations; ++bp_loc_idx) { SBBreakpointLocation bp_loc = bp.GetLocationAtIndex(bp_loc_idx); SBSymbolContext sc (bp_loc.GetAddress().GetSymbolContext(eSymbolContextEverything)); if (sc.IsValid()) { if (sc.GetBlock().GetContainingInlinedBlock().IsValid()) { // Skip inlined functions continue; } SBFunction function (sc.GetFunction()); if (function.IsValid()) { addr_t lo_pc = function.GetStartAddress().GetFileAddress(); if (lo_pc == LLDB_INVALID_ADDRESS) { // Skip functions that don't have concrete instances in the binary continue; } addr_t hi_pc = function.GetEndAddress().GetFileAddress(); const char *func_demangled_name = function.GetName(); const char *func_mangled_name = function.GetMangledName(); bool dump = true; const bool is_objc_method = ((func_demangled_name[0] == '-') || (func_demangled_name[0] == '+')) && (func_demangled_name[1] == '['); if (external_only) { // Dump all objective C methods, or external symbols dump = is_objc_method; if (!dump) dump = sc.GetSymbol().IsExternal(); } if (dump) { if (verbose) { printf ("\n name: %s\n", func_demangled_name); if (func_mangled_name) printf ("mangled: %s\n", func_mangled_name); printf (" range: [0x%16.16llx - 0x%16.16llx)\n type: ", lo_pc, hi_pc); } else { printf ("[0x%16.16llx - 0x%16.16llx) ", lo_pc, hi_pc); } SBType function_type = function.GetType(); SBType return_type = function_type.GetFunctionReturnType(); if (canonical) return_type = return_type.GetCanonicalType(); if (func_mangled_name && func_mangled_name[0] == '_' && func_mangled_name[1] == 'Z') { printf ("%s %s\n", return_type.GetName(), func_demangled_name); } else { SBTypeList function_args = function_type.GetFunctionArgumentTypes(); const size_t num_function_args = function_args.GetSize(); if (is_objc_method) { const char *class_name_start = func_demangled_name + 2; if (num_function_args == 0) { printf("%c(%s)[%s\n", func_demangled_name[0], return_type.GetName(), class_name_start); } else { const char *class_name_end = strchr(class_name_start,' '); const int class_name_len = class_name_end - class_name_start; printf ("%c(%s)[%*.*s", func_demangled_name[0], return_type.GetName(), class_name_len, class_name_len, class_name_start); const char *selector_pos = class_name_end + 1; for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args; ++function_arg_idx) { const char *selector_end = strchr(selector_pos, ':') + 1; const int selector_len = selector_end - selector_pos; SBType function_arg_type = function_args.GetTypeAtIndex(function_arg_idx); if (canonical) function_arg_type = function_arg_type.GetCanonicalType(); printf (" %*.*s", selector_len, selector_len, selector_pos); if (function_arg_type.IsValid()) { printf ("(%s)", function_arg_type.GetName()); } else { printf ("(?)"); } selector_pos = selector_end; } printf ("]\n"); } } else { printf ("%s ", return_type.GetName()); if (strchr (func_demangled_name, '(')) printf ("(*)("); else printf ("%s(", func_demangled_name); for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args; ++function_arg_idx) { SBType function_arg_type = function_args.GetTypeAtIndex(function_arg_idx); if (canonical) function_arg_type = function_arg_type.GetCanonicalType(); if (function_arg_type.IsValid()) { printf ("%s%s", function_arg_idx > 0 ? ", " : "", function_arg_type.GetName()); } else { printf ("%s???", function_arg_idx > 0 ? ", " : ""); } } printf (")\n"); } } } } } } } } } else { fprintf (stderr, "error: %s\n", error.GetCString()); exit(1); } } return 0; }
SBBreakpoint Xcode::CreateFileLineBreakpoint (SBTarget target, const char* file, uint32_t line) { return target.BreakpointCreateByLocation(file, line); }
SBSourceManager::SBSourceManager (const SBTarget &target) { m_opaque_ap.reset(new SourceManagerImpl (target.GetSP())); }