lldb-perf-stepping.cpp revision 177ac0db135db53edd2c6158d8e3190d2e78b566
1a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include <CoreFoundation/CoreFoundation.h>
2a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
3a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include "lldb-perf/lib/Timer.h"
4a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include "lldb-perf/lib/Metric.h"
5a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include "lldb-perf/lib/Measurement.h"
6a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include "lldb-perf/lib/TestCase.h"
7a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include "lldb-perf/lib/Xcode.h"
8a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
9a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include <unistd.h>
10a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham#include <string>
110b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham#include <getopt.h>
12a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
13a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Inghamusing namespace lldb_perf;
14a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
15a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Inghamclass StepTest : public TestCase
16a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham{
170b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    typedef void (*no_function) (void);
180b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
19a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Inghampublic:
200b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    StepTest(bool use_single_stepping = false) :
210b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        m_main_source("stepping-testcase.cpp"),
22094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        m_use_single_stepping(use_single_stepping),
23094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        m_time_measurements(nullptr)
24a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    {
25a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    }
26a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
27a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    virtual
28a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    ~StepTest() {}
29a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
309de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    virtual bool
31b1b36ec6dcfbe7c7dfa423d50cb7c2296deca68eEnrico Granata    Setup (int& argc, const char**& argv)
32a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    {
33a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham        TestCase::Setup (argc, argv);
34a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
350b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        // Toggle the fast stepping command on or off as required.
360b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const char *single_step_cmd = "settings set target.use-fast-stepping false";
370b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const char *fast_step_cmd   = "settings set target.use-fast-stepping true";
380b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const char *cmd_to_use;
390b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
400b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (m_use_single_stepping)
410b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            cmd_to_use = single_step_cmd;
420b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        else
430b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            cmd_to_use = fast_step_cmd;
440b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
450b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        SBCommandReturnObject return_object;
460b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        m_debugger.GetCommandInterpreter().HandleCommand(cmd_to_use,
470b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                                                         return_object);
480b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (!return_object.Succeeded())
490b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        {
500b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            if (return_object.GetError() != NULL)
510b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                printf ("Got an error running settings set: %s.\n", return_object.GetError());
520b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            else
530b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                printf ("Failed running settings set, no error.\n");
540b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        }
550b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
56a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham        m_target = m_debugger.CreateTarget(m_app_path.c_str());
570b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        m_first_bp = m_target.BreakpointCreateBySourceRegex("Here is some code to stop at originally.", m_main_source);
580b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
59a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham        const char* file_arg = m_app_path.c_str();
60a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham        const char* empty = nullptr;
61a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham        const char* args[] = {file_arg, empty};
629de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton        SBLaunchInfo launch_info (args);
63a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
649de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton        return Launch (launch_info);
65a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    }
66a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
67a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    void
680b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    WriteResults (Results &results)
69a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    {
700b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        // Gotta turn off the last timer now.
71094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        m_individual_step_times.push_back(m_time_measurements.Stop());
720b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
73094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        size_t num_time_measurements = m_individual_step_times.size();
74094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham
750b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        Results::Dictionary& results_dict = results.GetDictionary();
76094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        const char *short_format_string = "step-time-%0.2d";
770b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const size_t short_size = strlen(short_format_string) + 5;
780b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        char short_buffer[short_size];
790b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const char *long_format_string  = "The time it takes for step %d in the step sequence.";
800b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const size_t long_size = strlen(long_format_string) + 5;
810b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        char long_buffer[long_size];
829de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton
830b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        for (size_t i = 0; i < num_time_measurements; i++)
840b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        {
850b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            snprintf (short_buffer, short_size, short_format_string, i);
860b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            snprintf (long_buffer, long_size, long_format_string, i);
870b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
880b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            results_dict.AddDouble(short_buffer,
890b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                                   long_buffer,
90094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham                                   m_individual_step_times[i]);
910b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
920b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        }
93094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        results_dict.AddDouble ("total-time", "Total time spent stepping.", m_time_measurements.GetMetric().GetSum());
94177ac0db135db53edd2c6158d8e3190d2e78b566Enrico Granata        results_dict.AddDouble ("stddev-time", "StdDev of time spent stepping.", m_time_measurements.GetMetric().GetStandardDeviation());
95177ac0db135db53edd2c6158d8e3190d2e78b566Enrico Granata
960b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        results.Write(m_out_path.c_str());
979de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    }
989de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton
999de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton
1000b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    const char *
1010b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    GetExecutablePath () const
1020b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
1030b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (m_app_path.empty())
1040b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            return NULL;
1050b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        return m_app_path.c_str();
1060b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
1070b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1080b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    const char *
1090b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    GetResultFilePath () const
1100b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
1110b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (m_out_path.empty())
1120b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            return NULL;
1130b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        return m_out_path.c_str();
1140b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
1150b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1169de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    void
1170b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    SetExecutablePath (const char *path)
1189de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    {
1190b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (path && path[0])
1200b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            m_app_path = path;
1210b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        else
1220b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            m_app_path.clear();
1239de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    }
1249de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton
1250b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    void
1260b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    SetResultFilePath (const char *path)
1270b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
1280b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (path && path[0])
1290b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            m_out_path = path;
1300b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        else
1310b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            m_out_path.clear();
1320b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
1330b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1340b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    void
1350b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    SetUseSingleStep (bool use_it)
1360b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
1370b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        m_use_single_stepping = use_it;
1380b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
1399de4dec874148d30cc1d4c498d38cd048a8164caGreg Claytonprivate:
1409de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    virtual void
1419de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton	TestStep (int counter, ActionWanted &next_action)
1429de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    {
1430b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (counter > 0)
144094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        {
145094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham            m_individual_step_times.push_back(m_time_measurements.Stop());
146094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham
147094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        }
148094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham
149094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        // Disable the breakpoint, just in case it gets multiple locations we don't want that confusing the stepping.
1500b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (counter == 0)
1510b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            m_first_bp.SetEnabled(false);
1520b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1530b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        next_action.StepOver(m_process.GetThreadAtIndex(0));
154094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham        m_time_measurements.Start();
1550b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
156a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
157a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    }
158a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
1590b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    SBBreakpoint m_first_bp;
1600b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    SBFileSpec   m_main_source;
161094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham    TimeMeasurement<no_function> m_time_measurements;
162094e2a9b484381bd35d95090c7501b1e3880e92fJim Ingham    std::vector<double>          m_individual_step_times;
1630b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    bool m_use_single_stepping;
164a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    std::string m_app_path;
165a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    std::string m_out_path;
166a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
167a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
168a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham};
169a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
1700b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Inghamstruct Options
1710b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham{
1720b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    std::string test_file_path;
1730b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    std::string out_file;
1740b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    bool verbose;
1750b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    bool fast_step;
1760b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    bool error;
1770b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    bool print_help;
1780b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1790b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    Options() :
1800b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        verbose (false),
1810b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        fast_step (true),
1820b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        error (false),
1830b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        print_help (false)
1840b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
1850b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
1860b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham};
1870b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1880b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Inghamstatic struct option g_long_options[] = {
1890b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    { "verbose",      no_argument,            NULL, 'v' },
1900b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    { "single-step",  no_argument,            NULL, 's' },
1910b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    { "test-file",    required_argument,      NULL, 't' },
1920b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    { "out-file",     required_argument,      NULL, 'o' },
1930b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    { NULL,           0,                      NULL,  0  }
1940b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham};
1950b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1960b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
1970b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Inghamstd::string
1980b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim InghamGetShortOptionString (struct option *long_options)
199a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham{
2000b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    std::string option_string;
2010b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    for (int i = 0; long_options[i].name != NULL; ++i)
202a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    {
2030b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        if (long_options[i].flag == NULL)
2040b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        {
2050b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            option_string.push_back ((char) long_options[i].val);
2060b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            switch (long_options[i].has_arg)
2070b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            {
2080b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                default:
2090b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                case no_argument:
2100b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    break;
2110b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                case required_argument:
2120b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    option_string.push_back (':');
2130b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    break;
2140b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                case optional_argument:
2150b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    option_string.append (2, ':');
2160b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    break;
2170b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            }
2180b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        }
219a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    }
2200b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    return option_string;
2210b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham}
2220b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2230b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Inghamint main(int argc, const char * argv[])
2240b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham{
2250b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2263f2f741bb533b78e2fac5332c4698338ea2fd3acGreg Clayton    // Prepare for & make calls to getopt_long_only.
2270b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2280b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    std::string short_option_string (GetShortOptionString(g_long_options));
229a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham
2309de4dec874148d30cc1d4c498d38cd048a8164caGreg Clayton    StepTest test;
2310b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2320b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    Options option_data;
2330b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    bool done = false;
2340b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2350b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham#if __GLIBC__
2360b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    optind = 0;
2370b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham#else
2380b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    optreset = 1;
2390b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    optind = 1;
2400b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham#endif
2410b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    while (!done)
2420b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
2430b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        int long_options_index = -1;
2440b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        const int short_option = ::getopt_long_only (argc,
2450b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                                                     const_cast<char **>(argv),
2460b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                                                     short_option_string.c_str(),
2470b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                                                     g_long_options,
2480b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                                                     &long_options_index);
2490b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2500b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        switch (short_option)
2510b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        {
2520b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case 0:
2530b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                // Already handled
2540b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2550b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2560b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case -1:
2570b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                done = true;
2580b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2590b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2600b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case '?':
2610b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                option_data.print_help = true;
2620b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2630b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2640b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case 'h':
2650b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                option_data.print_help = true;
2660b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2670b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2680b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case 'v':
2690b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                option_data.verbose = true;
2700b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2710b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2720b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case 's':
2730b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                option_data.fast_step = false;
2740b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                test.SetUseSingleStep(true);
2750b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2760b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2770b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case 't':
2780b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                {
2790b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    SBFileSpec file(optarg);
2800b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    if (file.Exists())
2810b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                        test.SetExecutablePath(optarg);
2820b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                    else
2830b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                        fprintf(stderr, "error: file specified in --test-file (-t) option doesn't exist: '%s'\n", optarg);
2840b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                }
2850b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2860b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2870b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            case 'o':
2880b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                test.SetResultFilePath(optarg);
2890b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2900b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2910b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham            default:
2920b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                option_data.error = true;
2930b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                option_data.print_help = true;
2940b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                fprintf (stderr, "error: unrecognized option %c\n", short_option);
2950b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham                break;
2960b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        }
2970b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
2980b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
2990b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
3000b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    if (option_data.print_help)
3010b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
3020b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        puts(R"(
3030b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim InghamNAME
3040b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    lldb-perf-stepping -- a tool that measures LLDB peformance of simple stepping operations.
3050b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
3060b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim InghamSYNOPSIS
3070b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    lldb-perf-stepping --test-file=FILE [--out-file=PATH --verbose --fast-step]
3080b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
3090b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim InghamDESCRIPTION
3100b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    Runs a set of stepping operations, timing each step and outputs results
3110b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    to a plist file.
3120b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham)");
3130b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        exit(0);
3140b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
3150b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    if (option_data.error)
3160b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
3170b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        exit(1);
3180b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
3190b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
3200b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    if (test.GetExecutablePath() == NULL)
3210b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    {
3220b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        // --clang is mandatory
3230b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        option_data.print_help = true;
3240b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        option_data.error = true;
3250b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham        fprintf (stderr, "error: the '--test-file=PATH' option is mandatory\n");
3260b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    }
3270b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
3280b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    // Update argc and argv after parsing options
3290b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    argc -= optind;
3300b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    argv += optind;
3310b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham
3320b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    test.SetVerbose(true);
3330b51bed6fbaa9d63730d54a2891e9d73d5bec773Jim Ingham    TestCase::Run(test, argc, argv);
334a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham    return 0;
335a3df3b0c89ab584262098f8d877e8a72e3614a08Jim Ingham}
336