Bug 779625: Send telemetry metric when exceptions are thrown. (p=gcomnino,r=fklockii,r=rulohani)
authorDan Schaffer <Dan.Schaffer@adobe.com>
Fri, 17 Aug 2012 06:49:07 -0700
changeset 7528 cbe55af57d881b2b024ab95de3093141063dd1c2
parent 7527 3906079735e4fb6a2f99ca5c22739cf6eabc8393
child 7529 9190d6ad28a1611be018bace892214fd7b8f7380
push id4256
push userdschaffe@adobe.com
push dateMon, 20 Aug 2012 13:10:53 +0000
reviewersfklockii, rulohani
bugs779625, 1098924, 1101451
Bug 779625: Send telemetry metric when exceptions are thrown. (p=gcomnino,r=fklockii,r=rulohani) integrate CL 1098924 CL@1101451
core/AvmCore.cpp
core/AvmCore.h
--- a/core/AvmCore.cpp
+++ b/core/AvmCore.cpp
@@ -1623,16 +1623,38 @@ 22. Return false.
             }
             else
             {
                 exception->flags &= ~Exception::SEEN_BY_DEBUGGER;
             }
         }
         #endif
 
+#ifdef VMCFG_TELEMETRY_SAMPLER
+        // Send the exception info along with the stack trace over telemetry
+        if (!(exception->flags & Exception::SUPPRESS_ERROR_REPORT) && getTelemetry() && getTelemetry()->IsActive()) {
+            StringBuffer exceptionStringBuffer(this);
+            ScriptObject *so = atomToScriptObject(exception->atom);
+            if (so) {
+                // get the full class name including the namespace
+                so->traits()->print(exceptionStringBuffer, true);
+            } else {
+                // backup, just convert atom to a string, it will say "Error"
+                exceptionStringBuffer << StUTF8String(string(exception->atom)).c_str();
+            }
+            exceptionStringBuffer << '\n';
+
+            // Get the stack trace
+            GetStackTrace(exceptionStringBuffer);
+
+            // Send the metric as a string
+            TELEMETRY_STRING(getTelemetry(), ".as.exception", exceptionStringBuffer.c_str());
+        }
+#endif
+
         // exceptionFrame should not be NULL; if it is,
         // you are missing a TRY/CATCH block around
         // a call to an AVM+ method that throws an
         // exception.
         AvmAssert(exceptionFrame != NULL);
         exceptionFrame->throwException(exception);
     }
 
@@ -5470,16 +5492,30 @@ 22. Return false.
 
         return nFramesWritten;
     }
 
     avmplus::Stringp AvmCore::functionHandleToString(telemetry::FunctionHandle handle)
     {
         return ((MethodInfo*)handle)->getMethodName();
     }
+
+    void AvmCore::GetStackTrace(StringBuffer &buffer)
+    {
+        for (MethodFrame* curFrame = currentMethodFrame;
+             curFrame != NULL;
+             curFrame = curFrame->next) {
+            MethodEnv* env = curFrame->env();
+            if (env && env->method) {
+                avmplus::Stringp pStrFunc = functionHandleToString(env->method);
+                avmplus::StUTF8String methodNameUtf8(pStrFunc);
+                buffer << methodNameUtf8.c_str() << '\n';
+            }
+        }
+    }
 #endif
 
     /* static */
     void AvmCore::handleStackOverflowMethodEnv(MethodEnv* env)
     {
         handleStackOverflowToplevel(env->toplevel());
     }
 
--- a/core/AvmCore.h
+++ b/core/AvmCore.h
@@ -630,16 +630,20 @@ const int kBufferPadding = 16;
         // first in the buffer.
         unsigned int recordCallStack(telemetry::FunctionHandle* stackBuffer, unsigned int maxDepth);
 
         // Find out the function name corresponding to a given call stack item.
         // We retain ownership of the object pointed to by the returned pointer.
         // This function can be called from the host at any time, not only from inside takeSample().
         avmplus::Stringp functionHandleToString(telemetry::FunctionHandle item);
 
+        // Dumps the current MethodFrame stack to the given string buffer.
+        // This stack trace works on Release player builds as well.
+        void GetStackTrace(StringBuffer &buffer);
+
         /*
           Functions and data that support sampling.
         */
 
         /** if non-zero, it means that the VM should call takeSample() or takeSampleWrapper() as soon as possible. */
         unsigned int    sampleTicks;
 
         /** whether or not the sampler is currently enabled */