[Lldb-commits] [lldb] r183961 - Added the ability options to:
Greg Clayton
gclayton at apple.com
Thu Jun 13 17:30:23 PDT 2013
Author: gclayton
Date: Thu Jun 13 19:30:23 2013
New Revision: 183961
URL: http://llvm.org/viewvc/llvm-project?rev=183961&view=rev
Log:
Added the ability options to:
- specify the architecture
- specify the platform
- specify if only external symbols should be dumped
- specify if types in the function signatures should be canonicalized
Modified:
lldb/trunk/examples/functions/main.cpp
Modified: lldb/trunk/examples/functions/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/functions/main.cpp?rev=183961&r1=183960&r2=183961&view=diff
==============================================================================
--- lldb/trunk/examples/functions/main.cpp (original)
+++ lldb/trunk/examples/functions/main.cpp Thu Jun 13 19:30:23 2013
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include <getopt.h>
#include <stdint.h>
#include <stdlib.h>
@@ -25,6 +26,8 @@
#include "LLDB/SBProcess.h"
#endif
+#include <string>
+
using namespace lldb;
//----------------------------------------------------------------------
@@ -57,123 +60,302 @@ public:
SBDebugger::Terminate();
}
};
+
+static struct option g_long_options[] =
+{
+ { "arch", required_argument, NULL, 'a' },
+ { "canonical", no_argument, NULL, 'c' },
+ { "extern", no_argument, NULL, 'x' },
+ { "help", no_argument, NULL, 'h' },
+ { "platform", required_argument, NULL, 'p' },
+ { "verbose", no_argument, NULL, 'v' },
+ { NULL, 0, NULL, 0 }
+};
+
+#define PROGRAM_NAME "lldb-functions"
+void
+usage ()
+{
+ puts (
+ "NAME\n"
+ " " PROGRAM_NAME " -- extract all function signatures from one or more binaries.\n"
+ "\n"
+ "SYNOPSIS\n"
+ " " PROGRAM_NAME " [[--arch=<ARCH>] [--platform=<PLATFORM>] [--verbose] [--help] [--canonical] --] <PATH> [<PATH>....]\n"
+ "\n"
+ "DESCRIPTION\n"
+ " Loads the executable pointed to by <PATH> and dumps complete signatures for all functions that have debug information.\n"
+ "\n"
+ "EXAMPLE\n"
+ " " PROGRAM_NAME " --arch=x86_64 /usr/lib/dyld\n"
+ );
+ exit(0);
+}
int
main (int argc, char const *argv[])
{
// Use a sentry object to properly initialize/terminate LLDB.
LLDBSentry sentry;
- if (argc < 2)
- exit (1);
+ 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 char *arch = NULL; // Fill this in with "x86_64" or "i386" as needed
- const char *platform = NULL; // Leave NULL for native platform, set to a valid other platform name if required
const bool add_dependent_libs = false;
SBError error;
- for (int arg_idx = 1; arg_idx < argc; ++arg_idx)
+ for (int arg_idx = 0; arg_idx < argc; ++arg_idx)
{
- // The first argument is the file path we want to look something up in
+ // The first argument is the file path we want to look something up in
const char *exe_file_path = argv[arg_idx];
- // Create a debugger instance so we can create a target
- SBDebugger debugger (SBDebugger::Create());
+ // Create a target using the executable.
+ SBTarget target = debugger.CreateTarget (exe_file_path,
+ arch,
+ platform,
+ add_dependent_libs,
+ error);
- if (debugger.IsValid())
+ if (error.Success())
{
- // 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())
{
- if (target.IsValid())
- {
- SBFileSpec exe_file_spec (exe_file_path, true);
- SBModule module (target.FindModule (exe_file_spec));
- SBFileSpecList comp_unit_list;
+ SBFileSpec exe_file_spec (exe_file_path, true);
+ SBModule module (target.FindModule (exe_file_spec));
+ SBFileSpecList comp_unit_list;
- if (module.IsValid())
+ 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())
{
- 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);
- }
+ 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)
+ 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())
{
- 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())
{
- if (sc.GetBlock().GetContainingInlinedBlock().IsValid())
+ addr_t lo_pc = function.GetStartAddress().GetFileAddress();
+ if (lo_pc == LLDB_INVALID_ADDRESS)
{
- // Skip inlined functions
+ // Skip functions that don't have concrete instances in the binary
continue;
}
- SBFunction function (sc.GetFunction());
- if (function.IsValid())
+ 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)
{
- addr_t lo_pc = function.GetStartAddress().GetFileAddress();
- if (lo_pc == LLDB_INVALID_ADDRESS)
+ // Dump all objective C methods, or external symbols
+ dump = is_objc_method;
+ if (!dump)
+ dump = sc.GetSymbol().IsExternal();
+ }
+
+ if (dump)
+ {
+ if (verbose)
{
- // Skip functions that don't have concrete instances in the binary
- continue;
+ 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);
}
- addr_t hi_pc = function.GetEndAddress().GetFileAddress();
-
- printf ("\nfunction name: %s\n", function.GetName());
- printf ("function range:[0x%llx - 0x%llx)\n", lo_pc, hi_pc);
SBType function_type = function.GetType();
SBType return_type = function_type.GetFunctionReturnType();
- if (return_type.IsValid())
+
+ if (canonical)
+ return_type = return_type.GetCanonicalType();
+
+ if (func_mangled_name &&
+ func_mangled_name[0] == '_' &&
+ func_mangled_name[1] == 'Z')
{
- printf ("return type: %s\n", return_type.GetName());
+ printf ("%s %s\n", return_type.GetName(), func_demangled_name);
}
- else
+ else
{
- printf ("return type: <NONE>\n");
- }
+ SBTypeList function_args = function_type.GetFunctionArgumentTypes();
+ const size_t num_function_args = function_args.GetSize();
-
- SBTypeList function_args = function_type.GetFunctionArgumentTypes();
- const size_t num_function_args = function_args.GetSize();
- 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 (function_arg_type.IsValid())
+ if (is_objc_method)
{
- printf ("arg[%u] type: %s\n", function_arg_idx, function_arg_type.GetName());
+ 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 ("arg[%u] type: <invalid>\n", function_arg_idx);
- }
+ 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);
- }
+ }
+ else
+ {
+ fprintf (stderr, "error: %s\n", error.GetCString());
+ exit(1);
}
}
More information about the lldb-commits
mailing list