aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2012-01-04 14:35:36 -0800
committerBen Cheng <bccheng@google.com>2012-01-04 14:35:36 -0800
commit529d868851ce83328c89429d256e68afe320c51d (patch)
treeaad7bde4e9e9c760fae364cde4e269a5261fbd88
parent444f6f98041242e2f8ddad3fedff6c59a5da9873 (diff)
downloadoprofile-529d868851ce83328c89429d256e68afe320c51d.tar.gz
Support multiple profile sessions w/o the need of rebooting.
Bonus changes: - Eliminated sending unnecessary SIGHUP to oprofiled when dumping samples. - fixed a file descriptor leak in read_num(). Change-Id: I79ca35a62df848ceb4e16f2bc62e54b86ab7495f
-rw-r--r--opcontrol/opcontrol.cpp69
1 files changed, 50 insertions, 19 deletions
diff --git a/opcontrol/opcontrol.cpp b/opcontrol/opcontrol.cpp
index 075ade6..6b440e2 100644
--- a/opcontrol/opcontrol.cpp
+++ b/opcontrol/opcontrol.cpp
@@ -342,10 +342,32 @@ void setup_session_dir()
}
}
+int read_num(const char* file)
+{
+ char buffer[256];
+ int fd = open(file, O_RDONLY);
+ if (fd<0) return -1;
+ int rd = read(fd, buffer, sizeof(buffer)-1);
+ buffer[rd] = 0;
+ close(fd);
+ return atoi(buffer);
+}
+
int do_setup()
{
char dir[1024];
+ /*
+ * Kill the old daemon so that setup can be done more than once to achieve
+ * the same effect as reset.
+ */
+ int num = read_num(OP_DATA_DIR"/lock");
+ if (num >= 0) {
+ printf("Terminating the old daemon...\n");
+ kill(num, SIGTERM);
+ sleep(5);
+ }
+
setup_session_dir();
if (mkdir(OP_DRIVER_BASE, 0755)) {
@@ -471,16 +493,6 @@ int echo_dev(const char* str, int val, const char* file, int counter)
return 0;
}
-int read_num(const char* file)
-{
- char buffer[256];
- int fd = open(file, O_RDONLY);
- if (fd<0) return -1;
- int rd = read(fd, buffer, sizeof(buffer)-1);
- buffer[rd] = 0;
- return atoi(buffer);
-}
-
void do_status()
{
int num;
@@ -517,7 +529,7 @@ void do_status()
sprintf(fullname, "/proc/%d", num);
fd = open(fullname, O_RDONLY);
if (fd == -1) {
- printf("Session directory is not clean - do \"opcontrol --setup\""
+ printf("OProfile daemon exited prematurely - redo setup"
" before you continue\n");
return;
}
@@ -561,11 +573,8 @@ void do_status()
closedir(dir);
}
-#if defined(__i386__) || defined(__x86_64__)
- /* FIXME on ARM - backtrace seems broken there */
num = read_num(OP_DRIVER_BASE"/backtrace_depth");
- printf(" %9u backtrace_depth\n", num);
-#endif
+ printf("backtrace_depth: %u\n", num);
}
}
else {
@@ -575,6 +584,20 @@ void do_status()
void do_reset()
{
+ /*
+ * Sending SIGHUP will result in the following crash in oprofiled when
+ * profiling subsequent runs:
+ * Stack Trace:
+ * RELADDR FUNCTION FILE:LINE
+ * 00008cd8 add_node+12 oprofilelibdb/db_insert.c:32
+ * 00008d69 odb_update_node_with_offset+60 oprofilelibdb/db_insert.c:102
+ *
+ * However without sending SIGHUP oprofile cannot be restarted successfully.
+ * As a temporary workaround, change do_reset into a no-op for now and kill
+ * the old daemon in do_setup to start all over again as a heavy-weight
+ * reset.
+ */
+#if 0
int fd;
fd = open(OP_DATA_DIR"/samples/current", O_RDONLY);
@@ -583,6 +606,13 @@ void do_reset()
}
close(fd);
system("rm -r "OP_DATA_DIR"/samples/current");
+ int num = read_num(OP_DATA_DIR"/lock");
+
+ if (num >= 0) {
+ printf("Signalling daemon...\n");
+ kill(num, SIGHUP);
+ }
+#endif
}
int main(int argc, char * const argv[])
@@ -630,10 +660,6 @@ int main(int argc, char * const argv[])
/* --dump */ {
int pid = read_num(OP_DATA_DIR"/lock");
echo_dev("1", 0, "dump", -1);
- if (pid >= 0) {
- sleep(1);
- kill(pid, SIGHUP);
- }
break;
}
/* --shutdown */
@@ -824,6 +850,11 @@ int main(int argc, char * const argv[])
if (start) {
echo_dev("1", 0, "enable", -1);
+ int num = read_num(OP_DATA_DIR"/lock");
+
+ if (num >= 0) {
+ kill(num, SIGUSR1);
+ }
}
if (stop) {