|
|
@@ -28,74 +28,55 @@ __thread struct callchain_cursor callchain_cursor;
|
|
|
int
|
|
|
parse_callchain_report_opt(const char *arg)
|
|
|
{
|
|
|
- char *tok, *tok2;
|
|
|
+ char *tok;
|
|
|
char *endptr;
|
|
|
+ bool minpcnt_set = false;
|
|
|
|
|
|
symbol_conf.use_callchain = true;
|
|
|
|
|
|
if (!arg)
|
|
|
return 0;
|
|
|
|
|
|
- tok = strtok((char *)arg, ",");
|
|
|
- if (!tok)
|
|
|
- return -1;
|
|
|
-
|
|
|
- /* get the output mode */
|
|
|
- if (!strncmp(tok, "graph", strlen(arg))) {
|
|
|
- callchain_param.mode = CHAIN_GRAPH_ABS;
|
|
|
-
|
|
|
- } else if (!strncmp(tok, "flat", strlen(arg))) {
|
|
|
- callchain_param.mode = CHAIN_FLAT;
|
|
|
- } else if (!strncmp(tok, "fractal", strlen(arg))) {
|
|
|
- callchain_param.mode = CHAIN_GRAPH_REL;
|
|
|
- } else if (!strncmp(tok, "none", strlen(arg))) {
|
|
|
- callchain_param.mode = CHAIN_NONE;
|
|
|
- symbol_conf.use_callchain = false;
|
|
|
- return 0;
|
|
|
- } else {
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- /* get the min percentage */
|
|
|
- tok = strtok(NULL, ",");
|
|
|
- if (!tok)
|
|
|
- goto setup;
|
|
|
-
|
|
|
- callchain_param.min_percent = strtod(tok, &endptr);
|
|
|
- if (tok == endptr)
|
|
|
- return -1;
|
|
|
+ while ((tok = strtok((char *)arg, ",")) != NULL) {
|
|
|
+ if (!strncmp(tok, "none", strlen(tok))) {
|
|
|
+ callchain_param.mode = CHAIN_NONE;
|
|
|
+ symbol_conf.use_callchain = false;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
|
|
|
- /* get the print limit */
|
|
|
- tok2 = strtok(NULL, ",");
|
|
|
- if (!tok2)
|
|
|
- goto setup;
|
|
|
+ /* try to get the output mode */
|
|
|
+ if (!strncmp(tok, "graph", strlen(tok)))
|
|
|
+ callchain_param.mode = CHAIN_GRAPH_ABS;
|
|
|
+ else if (!strncmp(tok, "flat", strlen(tok)))
|
|
|
+ callchain_param.mode = CHAIN_FLAT;
|
|
|
+ else if (!strncmp(tok, "fractal", strlen(tok)))
|
|
|
+ callchain_param.mode = CHAIN_GRAPH_REL;
|
|
|
+ /* try to get the call chain order */
|
|
|
+ else if (!strncmp(tok, "caller", strlen(tok)))
|
|
|
+ callchain_param.order = ORDER_CALLER;
|
|
|
+ else if (!strncmp(tok, "callee", strlen(tok)))
|
|
|
+ callchain_param.order = ORDER_CALLEE;
|
|
|
+ /* try to get the sort key */
|
|
|
+ else if (!strncmp(tok, "function", strlen(tok)))
|
|
|
+ callchain_param.key = CCKEY_FUNCTION;
|
|
|
+ else if (!strncmp(tok, "address", strlen(tok)))
|
|
|
+ callchain_param.key = CCKEY_ADDRESS;
|
|
|
+ /* try to get the min percent */
|
|
|
+ else if (!minpcnt_set) {
|
|
|
+ callchain_param.min_percent = strtod(tok, &endptr);
|
|
|
+ if (tok == endptr)
|
|
|
+ return -1;
|
|
|
+ minpcnt_set = true;
|
|
|
+ } else {
|
|
|
+ /* try print limit at last */
|
|
|
+ callchain_param.print_limit = strtoul(tok, &endptr, 0);
|
|
|
+ if (tok == endptr)
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
|
|
|
- if (tok2[0] != 'c') {
|
|
|
- callchain_param.print_limit = strtoul(tok2, &endptr, 0);
|
|
|
- tok2 = strtok(NULL, ",");
|
|
|
- if (!tok2)
|
|
|
- goto setup;
|
|
|
+ arg = NULL;
|
|
|
}
|
|
|
|
|
|
- /* get the call chain order */
|
|
|
- if (!strncmp(tok2, "caller", strlen("caller")))
|
|
|
- callchain_param.order = ORDER_CALLER;
|
|
|
- else if (!strncmp(tok2, "callee", strlen("callee")))
|
|
|
- callchain_param.order = ORDER_CALLEE;
|
|
|
- else
|
|
|
- return -1;
|
|
|
-
|
|
|
- /* Get the sort key */
|
|
|
- tok2 = strtok(NULL, ",");
|
|
|
- if (!tok2)
|
|
|
- goto setup;
|
|
|
- if (!strncmp(tok2, "function", strlen("function")))
|
|
|
- callchain_param.key = CCKEY_FUNCTION;
|
|
|
- else if (!strncmp(tok2, "address", strlen("address")))
|
|
|
- callchain_param.key = CCKEY_ADDRESS;
|
|
|
- else
|
|
|
- return -1;
|
|
|
-setup:
|
|
|
if (callchain_register_param(&callchain_param) < 0) {
|
|
|
pr_err("Can't register callchain params\n");
|
|
|
return -1;
|