OSDN Git Service

Add FileDescriptor variation of startMethodTracing().
authorDianne Hackborn <hackbod@google.com>
Wed, 24 Jun 2009 02:21:10 +0000 (19:21 -0700)
committerDianne Hackborn <hackbod@google.com>
Wed, 24 Jun 2009 22:08:56 +0000 (15:08 -0700)
This is for bug #1829561 ("am profile" with bad filename kills process), which
will allow the am command to take care of opening the file and handing the
resulting fd over to the process to be profiled.

libcore/dalvik/src/main/java/dalvik/system/VMDebug.java
vm/Profile.c
vm/Profile.h
vm/native/dalvik_system_VMDebug.c

index d9f11ce..efc25d6 100644 (file)
@@ -16,6 +16,7 @@
 
 package dalvik.system;
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 
 /**
@@ -149,8 +150,22 @@ public final class VMDebug {
      * @param flags flags to control method tracing. The only one that
      * is currently defined is {@link #TRACE_COUNT_ALLOCS}.
      */
+    public static void startMethodTracing(String traceFileName,
+        int bufferSize, int flags) {
+        startMethodTracing(traceFileName, null, bufferSize, flags);
+    }
+
+    /**
+     * Like startMethodTracing(String, int, int), but taking an already-opened
+     * FileDescriptor in which the trace is written.  The file name is also
+     * supplied simply for logging.  Makes a dup of the file descriptor.
+     * 
+     * Not exposed in the SDK unless we are really comfortable with supporting
+     * this and find it would be useful.
+     * @hide
+     */
     public static native void startMethodTracing(String traceFileName,
-        int bufferSize, int flags);
+        FileDescriptor fd, int bufferSize, int flags);
 
     /**
      * Determine whether method tracing is currently active.
index 8c731f9..8e19b34 100644 (file)
@@ -320,12 +320,14 @@ static void dumpMethodList(FILE* fp)
 }
 
 /*
- * Start method tracing.  This opens the file and allocates the buffer.
+ * Start method tracing.  This opens the file (if an already open fd has not
+ * been supplied) and allocates the buffer.
  * If any of these fail, we throw an exception and return.
  *
  * Method tracing is global to the VM.
  */
-void dvmMethodTraceStart(const char* traceFileName, int bufferSize, int flags)
+void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
+        int flags)
 {
     MethodTraceState* state = &gDvm.methodTrace;
 
@@ -351,7 +353,11 @@ void dvmMethodTraceStart(const char* traceFileName, int bufferSize, int flags)
         dvmThrowException("Ljava/lang/InternalError;", "buffer alloc failed");
         goto fail;
     }
-    state->traceFile = fopen(traceFileName, "w");
+    if (traceFd < 0) {
+        state->traceFile = fopen(traceFileName, "w");
+    } else {
+        state->traceFile = fdopen(traceFd, "w");
+    }
     if (state->traceFile == NULL) {
         LOGE("Unable to open trace file '%s': %s\n",
             traceFileName, strerror(errno));
index cdaf027..d5dbea2 100644 (file)
@@ -96,7 +96,8 @@ typedef struct AllocProfState {
 /*
  * Start/stop method tracing.
  */
-void dvmMethodTraceStart(const char* traceFileName, int bufferSize, int flags);
+void dvmMethodTraceStart(const char* traceFileName, int traceFd, int bufferSize,
+        int flags);
 bool dvmIsMethodTraceActive(void);
 void dvmMethodTraceStop(void);
 
index ec6d92e..bf7ce61 100644 (file)
@@ -209,7 +209,7 @@ static void Dalvik_dalvik_system_VMDebug_resetAllocCount(const u4* args,
 }
 
 /*
- * static void startMethodTracing(String traceFileName,
+ * static void startMethodTracing(String traceFileName, java.io.FileDescriptor,
  *     int bufferSize, int flags)
  *
  * Start method trace profiling.
@@ -219,8 +219,9 @@ static void Dalvik_dalvik_system_VMDebug_startMethodTracing(const u4* args,
 {
 #ifdef WITH_PROFILER
     StringObject* traceFileStr = (StringObject*) args[0];
-    int bufferSize = args[1];
-    int flags = args[2];
+    DataObject* traceFd = (DataObject*) args[1];
+    int bufferSize = args[2];
+    int flags = args[3];
     char* traceFileName;
 
     if (bufferSize == 0) {
@@ -229,13 +230,24 @@ static void Dalvik_dalvik_system_VMDebug_startMethodTracing(const u4* args,
     }
 
     if (traceFileStr == NULL || bufferSize < 1024) {
-        dvmThrowException("Ljava/lang/InvalidArgument;", NULL);
+        dvmThrowException("Ljava/lang/IllegalArgumentException;", NULL);
         RETURN_VOID();
     }
 
     traceFileName = dvmCreateCstrFromString(traceFileStr);
 
-    dvmMethodTraceStart(traceFileName, bufferSize, flags);
+    int fd = -1;
+    if (traceFd != NULL) {
+        InstField* field = dvmFindInstanceField(traceFd->obj.clazz, "descriptor", "I");
+        if (field == NULL) {
+            dvmThrowException("Ljava/lang/NoSuchFieldException;",
+                "No FileDescriptor.descriptor field");
+            RETURN_VOID();
+        }
+        fd = dup(dvmGetFieldInt(&traceFd->obj, field->byteOffset));
+    }
+    
+    dvmMethodTraceStart(traceFileName, fd, bufferSize, flags);
     free(traceFileName);
 #else
     // throw exception?
@@ -585,7 +597,7 @@ const DalvikNativeMethod dvm_dalvik_system_VMDebug[] = {
         Dalvik_dalvik_system_VMDebug_startAllocCounting },
     { "stopAllocCounting",          "()V",
         Dalvik_dalvik_system_VMDebug_stopAllocCounting },
-    { "startMethodTracing",         "(Ljava/lang/String;II)V",
+    { "startMethodTracing",         "(Ljava/lang/String;Ljava/io/FileDescriptor;II)V",
         Dalvik_dalvik_system_VMDebug_startMethodTracing },
     { "isMethodTracingActive",      "()Z",
         Dalvik_dalvik_system_VMDebug_isMethodTracingActive },