From d72d9f73b6ff93f11e9bc4360d4c7bf2e76d1eec Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Sat, 3 Mar 2012 06:37:05 -0500
Subject: [PATCH] Add debugging output in case LLLeap writes corrupt data to
 plugin. New llleap_test.cpp load testing turned up Windows issue in which
 plugin process received corrupt packet, producing LLSDParseError. Add code to
 dump the bad packet in that case -- but if LLSDParseError is willing to state
 the offset of the problem, not ALL of the packet. Quiet MSVC warning about
 little internal base class needing virtual destructor.

---
 indra/llcommon/tests/llleap_test.cpp | 31 +++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index 328b9c35624..4fb80df788f 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -86,6 +86,7 @@ namespace tut
             reader(".py",
                    // This logic is adapted from vita.viewerclient.receiveEvent()
                    boost::lambda::_1 <<
+                   "import re\n"
                    "import os\n"
                    "import sys\n"
                    // Don't forget that this Python script is written to some
@@ -128,7 +129,33 @@ namespace tut
                    "        parts[-1] = parts[-1][:excess]\n"
                    "    data = ''.join(parts)\n"
                    "    assert len(data) == length\n"
-                   "    return llsd.parse(data)\n"
+                   "    try:\n"
+                   "        return llsd.parse(data)\n"
+                   "    except llsd.LLSDParseError, e:\n"
+                   "        print >>sys.stderr, 'Bad received packet (%s), %s bytes:' % \\\n"
+                   "              (e, len(data))\n"
+                   "        showmax = 40\n"
+                   //       We've observed failures with very large packets;
+                   //       dumping the entire packet wastes time and space.
+                   //       But if the error states a particular byte offset,
+                   //       truncate to (near) that offset when dumping data.
+                   "        location = re.search(r' at byte ([0-9]+)', str(e))\n"
+                   "        if not location:\n"
+                   "            # didn't find offset, dump whole thing, no ellipsis\n"
+                   "            ellipsis = ''\n"
+                   "        else:\n"
+                   "            # found offset within error message\n"
+                   "            trunc = int(location.group(1)) + showmax\n"
+                   "            data = data[:trunc]\n"
+                   "            ellipsis = '... (%s more)' % (length - trunc)\n"
+                   "        offset = -showmax\n"
+                   "        for offset in xrange(0, len(data)-showmax, showmax):\n"
+                   "            print >>sys.stderr, '%04d: %r +' % \\\n"
+                   "                  (offset, data[offset:offset+showmax])\n"
+                   "        offset += showmax\n"
+                   "        print >>sys.stderr, '%04d: %r%s' % \\\n"
+                   "              (offset, data[offset:], ellipsis)\n"
+                   "        raise\n"
                    "\n"
                    "# deal with initial stdin message\n"
                    // this will throw if the initial write to stdin doesn't
@@ -294,6 +321,8 @@ namespace tut
             mPump.listen(name, boost::bind(&ListenerBase::call, this, _1));
         }
 
+        virtual ~ListenerBase() {}  // pacify MSVC
+
         virtual bool call(const LLSD& request)
         {
             return false;
-- 
GitLab