Exemplo n.º 1
0
char *
formatFrame (StringB &framedescB, SBFrame frame, FrameDetails framedetails)
{
	logprintf (LOG_TRACE, "formatFrame (0x%x, 0x%x, 0x%x)\n", &framedescB, &frame, framedetails);
	int frameid = frame.GetFrameID();
	SBAddress addr = frame.GetPCAddress();
	uint32_t file_addr = addr.GetFileAddress();
	SBFunction function = addr.GetFunction();
	char levelstring[NAME_MAX];
	if (framedetails&WITH_LEVEL)
		snprintf (levelstring, sizeof(levelstring), "level=\"%d\",", frameid);
	else
		levelstring[0] = '\0';

	const char *modulefilename = "";
	SBModule module = frame.GetModule();
	if (module.IsValid()) {
		SBFileSpec modulefilespec = module.GetPlatformFileSpec();
		modulefilename = modulefilespec.GetFilename();
	}

	const char *func_name="??";
	static StringB argsstringB(LINE_MAX);
	argsstringB.clear();
	if (function.IsValid()) {
		const char *filename, *filedir;
		int line = 0;
		func_name = function.GetName();
		SBLineEntry line_entry = addr.GetLineEntry();
		SBFileSpec filespec = line_entry.GetFileSpec();
		filename = filespec.GetFilename();
		filedir = filespec.GetDirectory();
		line = line_entry.GetLine();
		if (framedetails&WITH_ARGS) {
			SBValueList args = frame.GetVariables(1,0,0,0);
			static StringB argsdescB(LINE_MAX);
			argsdescB.clear();
			SBFunction function = frame.GetFunction();
			formatVariables (argsdescB, args);
			argsstringB.catsprintf ("%sargs=[%s]", (framedetails==JUST_LEVEL_AND_ARGS)?"":",", argsdescB.c_str());
		}
		if (framedetails==JUST_LEVEL_AND_ARGS)
			framedescB.catsprintf ("frame={%s%s}", levelstring, argsstringB.c_str());
		else
			framedescB.catsprintf ("frame={%saddr=\"0x%016x\",func=\"%s\"%s,file=\"%s\","
								"fullname=\"%s/%s\",line=\"%d\"}",
								levelstring,file_addr,func_name,argsstringB.c_str(),filename,filedir,filename,line);
	}
	else {
		if (framedetails&WITH_ARGS)
			argsstringB.catsprintf ("%sargs=[]", (framedetails==JUST_LEVEL_AND_ARGS)?"":",");
		if (framedetails==JUST_LEVEL_AND_ARGS)
			framedescB.catsprintf ("frame={%s%s}", levelstring, argsstringB.c_str());
		else {
			func_name = frame.GetFunctionName();
			framedescB.catsprintf ("frame={%saddr=\"0x%016x\",func=\"%s\"%s,file=\"%s\"}",
					levelstring, file_addr, func_name, argsstringB.c_str(), modulefilename);
		}
	}
	return framedescB.c_str();
}
Exemplo n.º 2
0
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;
}