blob: 3f27b3993acb7cc838e100e128546f7f7f7a6de2 [file] [log] [blame]
Greg Clayton07a1d372013-06-13 18:03:11 +00001//===-- main.cpp ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include <stdint.h>
11#include <stdlib.h>
12
Greg Clayton1767a732013-06-13 21:27:14 +000013#if defined(__APPLE__)
Greg Clayton07a1d372013-06-13 18:03:11 +000014#include <LLDB/LLDB.h>
Greg Clayton1767a732013-06-13 21:27:14 +000015#else
16#include "LLDB/SBBlock.h"
17#include "LLDB/SBCompileUnit.h"
18#include "LLDB/SBDebugger.h"
19#include "LLDB/SBFunction.h"
20#include "LLDB/SBModule.h"
21#include "LLDB/SBStream.h"
22#include "LLDB/SBSymbol.h"
23#include "LLDB/SBTarget.h"
24#include "LLDB/SBThread.h"
25#include "LLDB/SBProcess.h"
26#endif
Greg Clayton07a1d372013-06-13 18:03:11 +000027
28using namespace lldb;
29
30//----------------------------------------------------------------------
31// This quick sample code shows how to create a debugger instance and
32// create an executable target without adding dependent shared
33// libraries. It will then set a regular expression breakpoint to get
34// breakpoint locations for all functions in the module, and use the
35// locations to extract the symbol context for each location. Then it
36// dumps all // information about the function: its name, file address
37// range, the return type (if any), and all argument types.
38//
39// To build the program, type (while in this directory):
40//
41// $ make
42//
43// then to run this on MacOSX, specify the path to your LLDB.framework
44// library using the DYLD_FRAMEWORK_PATH option and run the executable
45//
46// $ DYLD_FRAMEWORK_PATH=/Volumes/data/lldb/tot/build/Debug ./a.out executable_path1 [executable_path2 ...]
47//----------------------------------------------------------------------
48class LLDBSentry
49{
50public:
51 LLDBSentry() {
52 // Initialize LLDB
53 SBDebugger::Initialize();
54 }
55 ~LLDBSentry() {
56 // Terminate LLDB
57 SBDebugger::Terminate();
58 }
59};
60int
61main (int argc, char const *argv[])
62{
63 // Use a sentry object to properly initialize/terminate LLDB.
64 LLDBSentry sentry;
65
66 if (argc < 2)
67 exit (1);
68
69 const char *arch = NULL; // Fill this in with "x86_64" or "i386" as needed
70 const char *platform = NULL; // Leave NULL for native platform, set to a valid other platform name if required
71 const bool add_dependent_libs = false;
72 SBError error;
73 for (int arg_idx = 1; arg_idx < argc; ++arg_idx)
74 {
75 // The first argument is the file path we want to look something up in
76 const char *exe_file_path = argv[arg_idx];
77
78 // Create a debugger instance so we can create a target
79 SBDebugger debugger (SBDebugger::Create());
80
81 if (debugger.IsValid())
82 {
83 // Create a target using the executable.
84 SBTarget target = debugger.CreateTarget (exe_file_path,
85 arch,
86 platform,
87 add_dependent_libs,
88 error);
89
90 if (error.Success())
91 {
92 if (target.IsValid())
93 {
94 SBFileSpec exe_file_spec (exe_file_path, true);
95 SBModule module (target.FindModule (exe_file_spec));
96 SBFileSpecList comp_unit_list;
97
98 if (module.IsValid())
99 {
100 char command[1024];
101 lldb::SBCommandReturnObject command_result;
102 snprintf (command, sizeof(command), "add-dsym --uuid %s", module.GetUUIDString());
103 debugger.GetCommandInterpreter().HandleCommand (command, command_result);
104 if (!command_result.Succeeded())
105 {
106 fprintf (stderr, "error: couldn't locate debug symbols for '%s'\n", exe_file_path);
107 exit(1);
108 }
109
110 SBFileSpecList module_list;
111 module_list.Append(exe_file_spec);
112 SBBreakpoint bp = target.BreakpointCreateByRegex (".", module_list, comp_unit_list);
113
114 const size_t num_locations = bp.GetNumLocations();
115 for (uint32_t bp_loc_idx=0; bp_loc_idx<num_locations; ++bp_loc_idx)
116 {
117 SBBreakpointLocation bp_loc = bp.GetLocationAtIndex(bp_loc_idx);
118 SBSymbolContext sc (bp_loc.GetAddress().GetSymbolContext(eSymbolContextEverything));
119 if (sc.IsValid())
120 {
121 if (sc.GetBlock().GetContainingInlinedBlock().IsValid())
122 {
123 // Skip inlined functions
124 continue;
125 }
126 SBFunction function (sc.GetFunction());
127 if (function.IsValid())
128 {
129 addr_t lo_pc = function.GetStartAddress().GetFileAddress();
130 if (lo_pc == LLDB_INVALID_ADDRESS)
131 {
132 // Skip functions that don't have concrete instances in the binary
133 continue;
134 }
135 addr_t hi_pc = function.GetEndAddress().GetFileAddress();
136
137 printf ("\nfunction name: %s\n", function.GetName());
138 printf ("function range:[0x%llx - 0x%llx)\n", lo_pc, hi_pc);
139 SBType function_type = function.GetType();
140 SBType return_type = function_type.GetFunctionReturnType();
141 if (return_type.IsValid())
142 {
143 printf ("return type: %s\n", return_type.GetName());
144 }
145 else
146 {
147 printf ("return type: <NONE>\n");
148 }
149
150
151 SBTypeList function_args = function_type.GetFunctionArgumentTypes();
152 const size_t num_function_args = function_args.GetSize();
153 for (uint32_t function_arg_idx = 0; function_arg_idx < num_function_args; ++function_arg_idx)
154 {
155 SBType function_arg_type = function_args.GetTypeAtIndex(function_arg_idx);
156 if (function_arg_type.IsValid())
157 {
158 printf ("arg[%u] type: %s\n", function_arg_idx, function_arg_type.GetName());
159 }
160 else
161 {
162 printf ("arg[%u] type: <invalid>\n", function_arg_idx);
163 }
164 }
165
166 }
167 }
168 }
169 }
170 }
171 }
172 else
173 {
174 fprintf (stderr, "error: %s\n", error.GetCString());
175 exit(1);
176 }
177 }
178 }
179
180 return 0;
181}
182