aboutsummaryrefslogtreecommitdiff
path: root/opcontrol/opcontrol.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'opcontrol/opcontrol.cpp')
-rw-r--r--opcontrol/opcontrol.cpp128
1 files changed, 95 insertions, 33 deletions
diff --git a/opcontrol/opcontrol.cpp b/opcontrol/opcontrol.cpp
index 3eb0d28..075ade6 100644
--- a/opcontrol/opcontrol.cpp
+++ b/opcontrol/opcontrol.cpp
@@ -27,7 +27,10 @@
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
+#include <dirent.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
#include "op_config.h"
@@ -83,6 +86,7 @@ struct option long_options[] = {
{"shutdown", 0, 0, 'h'},
{"status", 0, 0, 't'},
{"verbose", 0, 0, 'V'},
+ {"verbose-log", 1, 0, 'l'},
{0, 0, 0, 0},
};
@@ -292,6 +296,8 @@ void usage()
" --list-events list event types\n"
" --help this message\n"
" --verbose show extra status\n"
+ " --verbose-log=lvl set daemon logging verbosity during setup\n"
+ " levels are: all,sfile,arcs,samples,module,misc\n"
" --setup setup directories\n"
#if defined(__i386__) || defined(__x86_64__)
" --quick setup and select CPU_CLK_UNHALTED:60000\n"
@@ -343,12 +349,17 @@ int do_setup()
setup_session_dir();
if (mkdir(OP_DRIVER_BASE, 0755)) {
- fprintf(stderr, "Cannot create directory "OP_DRIVER_BASE": %s\n",
- strerror(errno));
- return -1;
+ if (errno != EEXIST) {
+ fprintf(stderr, "Cannot create directory "OP_DRIVER_BASE": %s\n",
+ strerror(errno));
+ return -1;
+ }
}
- if (system("mount -t oprofilefs nodev "OP_DRIVER_BASE)) {
- return -1;
+
+ if (access(OP_DRIVER_BASE"/stats", F_OK)) {
+ if (system("mount -t oprofilefs nodev "OP_DRIVER_BASE)) {
+ return -1;
+ }
}
return 0;
}
@@ -417,7 +428,7 @@ int process_event(const char *event_spec)
return -1;
}
- /* Use defualt count */
+ /* Use default count */
if (count_name[0] == 0) {
count_val = min_count[0];
} else {
@@ -512,18 +523,46 @@ void do_status()
}
else {
close(fd);
+
printf("oprofiled pid: %d\n", num);
num = read_num(OP_DRIVER_BASE"/enable");
+
printf("profiler is%s running\n", num == 0 ? " not" : "");
- num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received");
- printf(" %9u samples received\n", num);
- num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_lost_overflow");
- printf(" %9u samples lost overflow\n", num);
+
+ DIR* dir = opendir(OP_DRIVER_BASE"/stats");
+ if (dir) {
+ for (struct dirent* dirent; !!(dirent = readdir(dir));) {
+ if (strlen(dirent->d_name) >= 4 && memcmp(dirent->d_name, "cpu", 3) == 0) {
+ char cpupath[256];
+ strcpy(cpupath, OP_DRIVER_BASE"/stats/");
+ strcat(cpupath, dirent->d_name);
+
+ strcpy(fullname, cpupath);
+ strcat(fullname, "/sample_received");
+ num = read_num(fullname);
+ printf(" %s %9u samples received\n", dirent->d_name, num);
+
+ strcpy(fullname, cpupath);
+ strcat(fullname, "/sample_lost_overflow");
+ num = read_num(fullname);
+ printf(" %s %9u samples lost overflow\n", dirent->d_name, num);
+
+ strcpy(fullname, cpupath);
+ strcat(fullname, "/sample_invalid_eip");
+ num = read_num(fullname);
+ printf(" %s %9u samples invalid eip\n", dirent->d_name, num);
+
+ strcpy(fullname, cpupath);
+ strcat(fullname, "/backtrace_aborted");
+ num = read_num(fullname);
+ printf(" %s %9u backtrace aborted\n", dirent->d_name, num);
+ }
+ }
+ closedir(dir);
+ }
#if defined(__i386__) || defined(__x86_64__)
/* FIXME on ARM - backtrace seems broken there */
- num = read_num(OP_DRIVER_BASE"/stats/cpu0/backtrace_aborted");
- printf(" %9u backtrace aborted\n", num);
num = read_num(OP_DRIVER_BASE"/backtrace_depth");
printf(" %9u backtrace_depth\n", num);
#endif
@@ -549,14 +588,15 @@ void do_reset()
int main(int argc, char * const argv[])
{
int option_index;
- char command[1024];
+ bool show_status = false;
+ char* verbose_log = NULL;
/* Initialize default strings */
strcpy(vmlinux, "--no-vmlinux");
strcpy(kernel_range, "");
while (1) {
- int c = getopt_long(argc, argv, "c:e:v:r:dhVt", long_options, &option_index);
+ int c = getopt_long(argc, argv, "c:e:v:r:dhVtl:", long_options, &option_index);
if (c == -1) {
break;
}
@@ -565,7 +605,7 @@ int main(int argc, char * const argv[])
break;
/* --callgraph */
case 'c':
- strncpy(callgraph, optarg, sizeof(callgraph));
+ strncpy(callgraph, optarg, sizeof(callgraph));
break;
/* --event */
case 'e':
@@ -605,7 +645,7 @@ int main(int argc, char * const argv[])
kill(pid, SIGTERM);/* Politely ask the daemon to die */
sleep(1);
kill(pid, SIGKILL);
- }
+ }
setup_session_dir();
break;
}
@@ -613,9 +653,13 @@ int main(int argc, char * const argv[])
case 'V':
verbose_print++;
break;
+ /* --verbose-log */
+ case 'l':
+ verbose_log = strdup(optarg);
+ break;
/* --status */
case 't':
- do_status();
+ show_status = true;
break;
default:
usage();
@@ -662,9 +706,12 @@ int main(int argc, char * const argv[])
}
if (num_events != 0 || timer != 0) {
+ char command[1024];
int i;
- strcpy(command, "oprofiled --session-dir="OP_DATA_DIR);
+ strcpy(command, argv[0]);
+ char* slash = strrchr(command, '/');
+ strcpy(slash ? slash + 1 : command, "oprofiled --session-dir="OP_DATA_DIR);
#if defined(__i386__) || defined(__x86_64__)
/* Nothing */
@@ -703,24 +750,21 @@ int main(int argc, char * const argv[])
}
#endif
-
/* Configure the counters and enable them */
for (i = 0; i < num_events; i++) {
int event_idx = selected_events[i];
int setup_result = 0;
if (i == 0) {
- snprintf(command+strlen(command), 1024 - strlen(command),
- " --events=");
- }
- else {
- snprintf(command+strlen(command), 1024 - strlen(command),
- ",");
+ snprintf(command + strlen(command), sizeof(command) - strlen(command),
+ " --events=");
+ } else {
+ snprintf(command + strlen(command), sizeof(command) - strlen(command), ",");
}
/* Compose name:id:count:unit_mask:kernel:user, something like
* --events=CYCLES_DATA_STALL:2:0:200000:0:1:1,....
*/
- snprintf(command+strlen(command), 1024 - strlen(command),
+ snprintf(command + strlen(command), sizeof(command) - strlen(command),
"%s:%d:%d:%d:%d:1:1",
event_info[event_idx].name,
event_info[event_idx].id,
@@ -750,18 +794,32 @@ int main(int argc, char * const argv[])
}
} else {
/* Timer mode uses empty event list */
- snprintf(command+strlen(command), 1024 - strlen(command),
- " --events=");
+ snprintf(command + strlen(command), sizeof(command) - strlen(command),
+ " --events=");
}
- snprintf(command+strlen(command), 1024 - strlen(command), " %s",
- vmlinux);
+ snprintf(command + strlen(command), sizeof(command) - strlen(command),
+ " %s", vmlinux);
if (kernel_range[0]) {
- snprintf(command+strlen(command), 1024 - strlen(command), " %s",
- kernel_range);
+ snprintf(command + strlen(command), sizeof(command) - strlen(command),
+ " %s", kernel_range);
}
+
+ if (verbose_log) {
+ snprintf(command + strlen(command), sizeof(command) - strlen(command),
+ " --verbose=%s", verbose_log);
+ }
+
+ printf("Starting oprofiled...\n");
verbose("command: %s\n", command);
- system(command);
+
+ int rc = system(command);
+ if (rc) {
+ fprintf(stderr, "Failed, oprofile returned exit code: %d\n", rc);
+ } else {
+ sleep(2);
+ printf("Ready\n");
+ }
}
if (start) {
@@ -772,4 +830,8 @@ int main(int argc, char * const argv[])
echo_dev("1", 0, "dump", -1);
echo_dev("0", 0, "enable", -1);
}
+
+ if (show_status) {
+ do_status();
+ }
}