]>
git.saurik.com Git - apple/system_cmds.git/blob - msa/main.cpp
5 // Created by James McIlree on 1/30/14.
6 // Copyright (c) 2014 Apple. All rights reserved.
9 #include <CPPUtil/CPPUtil.h>
13 bool isVerbose
= true;
14 bool shouldPrintVersion
= true;
15 std::vector
<std::string
> procsOfInterest
;
16 bool interestedInEverything
= false;
18 __attribute__((noreturn
)) void usage(const char *errorMsg
) {
20 printf("%s\n", errorMsg
);
24 // const char* BOLD = "\033[1m";
25 // const char* UNBOLD = "\033[0m";
27 // printf("01234567890123456789012345678901234567890123456789012345678901234567890123456789\n");
28 printf("msa [options]\n\n");
29 printf(" GLOBAL OPTIONS\n\n");
30 printf(" -h, --help Print this message\n");
31 printf(" --verbose Print additional information\n");
32 printf(" --version Print version info\n");
34 printf(" TRACE COLLECTION OPTIONS\n\n");
35 printf(" -i, --initialize # Set the size of the kernel trace buffer\n");
36 printf(" --no-voucher-contents Disable collecting voucher contents\n");
37 printf(" -L path Capture and save trace output to path\n");
39 printf(" OUTPUT OPTIONS\n\n");
40 printf(" --lifecycle all|user|none\n");
41 printf(" Set filter level for lifecycle events\n");
42 printf(" --mach-msg all|user|voucher|none\n");
43 printf(" Set filter level for mach msg events\n");
44 printf(" -o, --output path Print output to path\n");
45 printf(" --raw-timestamps Print timestamps as raw values, not deltas\n");
46 printf(" --mach-absolute-time Print timestamps in mach absolute time\n");
47 printf(" --event-index Print the index of each event\n");
52 template <typename SIZE
>
53 static bool check_interest_name(const MachineProcess
<SIZE
>& process
) {
54 if (interestedInEverything
)
57 const char* name
= process
.name();
58 for (auto& proc
: procsOfInterest
) {
59 if (strcmp(name
, proc
.c_str()) == 0)
66 static std::unique_ptr
<Action
> create_read_trace_file_action(const char* trace_file_path
) {
67 if (Path::is_file(trace_file_path
, true)) {
68 char resolved_path
[PATH_MAX
];
69 if (realpath(trace_file_path
, resolved_path
)) {
70 return std::make_unique
<ReadTraceFileAction
>(resolved_path
);
74 asprintf(&errmsg
, "%s does not exist or is not a file", trace_file_path
);
78 static std::vector
<std::unique_ptr
<Action
>> parse_arguments(int argc
, const char* argv
[], Globals
& globals
) {
81 std::vector
<std::unique_ptr
<Action
>> actions
;
84 const char* arg
= argv
[i
];
85 if ((strcmp(arg
, "-h") == 0) || (strcasecmp(arg
, "--help") == 0)) {
87 } else if ((strcmp(arg
, "-v") == 0) || strcasecmp(arg
, "--verbose") == 0) {
88 globals
.set_is_verbose(true);
89 } else if (strcasecmp(arg
, "--version") == 0) {
90 shouldPrintVersion
= true;
91 } else if ((strcmp(arg
, "-i") == 0) || strcasecmp(arg
, "--initialize") == 0) {
93 usage("--initialize requires an argument");
97 uint32_t temp
= (uint32_t)strtoul(arg
, &endptr
, 0);
99 globals
.set_trace_buffer_size(temp
);
101 usage("Unable to parse --initialize argument");
103 } else if (strcasecmp(arg
, "--no-voucher-contents") == 0) {
104 globals
.set_should_trace_voucher_contents(false);
105 } else if (strcasecmp(arg
, "-L") == 0) {
107 usage("-L requires an argument");
110 actions
.push_back(std::make_unique
<WriteTraceFileAction
>(arg
));
111 } else if (strcasecmp(arg
, "--lifecycle") == 0) {
113 usage("--lifecycle requires an argument");
116 if (strcasecmp(arg
, "all") == 0) {
117 globals
.set_lifecycle_filter(kLifecycleFilter::All
);
118 } else if (strcasecmp(arg
, "user") == 0) {
119 globals
.set_lifecycle_filter(kLifecycleFilter::User
);
120 } else if (strcasecmp(arg
, "none") == 0) {
121 globals
.set_lifecycle_filter(kLifecycleFilter::None
);
123 usage("Unrecognized --lifecycle value");
125 } else if (strcasecmp(arg
, "--mach-msg") == 0) {
127 usage("--mach-msg requires an argument");
130 if (strcasecmp(arg
, "all") == 0) {
131 globals
.set_mach_msg_filter(kMachMsgFilter::All
);
132 } else if (strcasecmp(arg
, "user") == 0) {
133 globals
.set_mach_msg_filter(kMachMsgFilter::User
);
134 } else if (strcasecmp(arg
, "voucher") == 0) {
135 globals
.set_mach_msg_filter(kMachMsgFilter::Voucher
);
136 } else if (strcasecmp(arg
, "none") == 0) {
137 globals
.set_mach_msg_filter(kMachMsgFilter::None
);
139 usage("Unrecognized --mach-msg value");
141 } else if ((strcmp(arg
, "-o") == 0) || strcasecmp(arg
, "--output") == 0) {
143 usage("--output requires an argument");
145 FileDescriptor
desc(argv
[i
], O_WRONLY
| O_CREAT
| O_TRUNC
, 0644);
146 if (!desc
.is_open()) {
148 asprintf(&errmsg
, "Unable to create output file at %s", argv
[i
]);
151 globals
.set_output_fd(std::move(desc
));
152 } else if (strcasecmp(arg
, "--raw-timestamps") == 0) {
153 globals
.set_should_zero_base_timestamps(false);
154 } else if (strcasecmp(arg
, "--mach-absolute-time") == 0) {
155 globals
.set_should_print_mach_absolute_timestamps(true);
156 } else if (strcasecmp(arg
, "--event-index") == 0) {
157 globals
.set_should_print_event_index(true);
160 // Last attempts to divine argument type/intent.
162 std::string
temp(arg
);
164 if (ends_with(temp
, ".trace")) {
165 actions
.push_back(create_read_trace_file_action(argv
[i
]));
172 char error_buffer
[PATH_MAX
];
173 snprintf(error_buffer
, sizeof(error_buffer
), "Unhandled argument: %s", arg
);
182 if (actions
.empty()) {
183 actions
.push_back(std::make_unique
<LiveTraceAction
>());
189 int main(int argc
, const char * argv
[])
192 // Use host values as defaults.
193 // User overrides as needed via flags.
196 auto actions
= parse_arguments(argc
, argv
, globals
);
198 interestedInEverything
= procsOfInterest
.empty();
200 // globals.set_should_print_mach_absolute_timestamps(true);
202 for (auto& action
: actions
) {
203 action
->execute(globals
);