diff --git a/src/node/examples/math.proto b/src/node/examples/math.proto
index e34ad5e9672791f1db5fc1a5e40973f95ab2cc40..311e148c021f66a8ed450e8258c60961314f546f 100644
--- a/src/node/examples/math.proto
+++ b/src/node/examples/math.proto
@@ -33,25 +33,25 @@ syntax = "proto3";
 package math;
 
 message DivArgs {
-  optional int64 dividend = 1;
-  optional int64 divisor = 2;
+  int64 dividend = 1;
+  int64 divisor = 2;
 }
 
 message DivReply {
-  optional int64 quotient = 1;
-  optional int64 remainder = 2;
+  int64 quotient = 1;
+  int64 remainder = 2;
 }
 
 message FibArgs {
-  optional int64 limit = 1;
+  int64 limit = 1;
 }
 
 message Num {
-  optional int64 num = 1;
+  int64 num = 1;
 }
 
 message FibReply {
-  optional int64 count = 1;
+  int64 count = 1;
 }
 
 service Math {
diff --git a/src/node/examples/route_guide.proto b/src/node/examples/route_guide.proto
index 442112823e5546d010def519ce8f1b44c5bbd77d..fceb632a97d9240871459ebb74cc1f757d42a326 100644
--- a/src/node/examples/route_guide.proto
+++ b/src/node/examples/route_guide.proto
@@ -66,18 +66,18 @@ service RouteGuide {
 // Latitudes should be in the range +/- 90 degrees and longitude should be in
 // the range +/- 180 degrees (inclusive).
 message Point {
-  optional int32 latitude = 1;
-  optional int32 longitude = 2;
+  int32 latitude = 1;
+  int32 longitude = 2;
 }
 
 // A latitude-longitude rectangle, represented as two diagonally opposite
 // points "lo" and "hi".
 message Rectangle {
   // One corner of the rectangle.
-  optional Point lo = 1;
+  Point lo = 1;
 
   // The other corner of the rectangle.
-  optional Point hi = 2;
+  Point hi = 2;
 }
 
 // A feature names something at a given point.
@@ -85,19 +85,19 @@ message Rectangle {
 // If a feature could not be named, the name is empty.
 message Feature {
   // The name of the feature.
-  optional string name = 1;
+  string name = 1;
 
   // The point where the feature is detected.
-  optional Point location = 2;
+  Point location = 2;
 }
 
 // A RouteNote is a message sent while at a given point.
 message RouteNote {
   // The location from which the message is sent.
-  optional Point location = 1;
+  Point location = 1;
 
   // The message to be sent.
-  optional string message = 2;
+  string message = 2;
 }
 
 // A RouteSummary is received in response to a RecordRoute rpc.
@@ -107,14 +107,14 @@ message RouteNote {
 // the distance between each point.
 message RouteSummary {
   // The number of points received.
-  optional int32 point_count = 1;
+  int32 point_count = 1;
 
   // The number of known features passed while traversing the route.
-  optional int32 feature_count = 2;
+  int32 feature_count = 2;
 
   // The distance covered in metres.
-  optional int32 distance = 3;
+  int32 distance = 3;
 
   // The duration of the traversal in seconds.
-  optional int32 elapsed_time = 4;
+  int32 elapsed_time = 4;
 }
diff --git a/src/node/examples/stock.proto b/src/node/examples/stock.proto
index 328e050aefb7025029ce9b6acad62191237cecee..5ee2bcbce66cbc72ad3bb2d533c634c0c1b8c8ad 100644
--- a/src/node/examples/stock.proto
+++ b/src/node/examples/stock.proto
@@ -33,13 +33,13 @@ package examples;
 
 // Protocol type definitions
 message StockRequest {
-  optional string symbol = 1;
-  optional int32 num_trades_to_watch = 2 [default=0];
+  string symbol = 1;
+  int32 num_trades_to_watch = 2;
 }
 
 message StockReply {
-  optional float price = 1;
-  optional string symbol = 2;
+  float price = 1;
+  string symbol = 2;
 }
 
 
diff --git a/src/node/interop/empty.proto b/src/node/interop/empty.proto
index 4295a0a960c0a07a7cf1df88438d3a8715a1b48b..6d0eb937d674ca3ee9aaf9c2ed8313250cd76647 100644
--- a/src/node/interop/empty.proto
+++ b/src/node/interop/empty.proto
@@ -28,7 +28,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto2";
+syntax = "proto3";
 
 package grpc.testing;
 
diff --git a/src/node/interop/messages.proto b/src/node/interop/messages.proto
index de0b1a232051052e2117f3718f21f040df06150c..7df85e3c13601ddc64e85a07eeadd502759a5761 100644
--- a/src/node/interop/messages.proto
+++ b/src/node/interop/messages.proto
@@ -30,7 +30,7 @@
 
 // Message definitions to be used by integration test service definitions.
 
-syntax = "proto2";
+syntax = "proto3";
 
 package grpc.testing;
 
@@ -49,46 +49,46 @@ enum PayloadType {
 // A block of data, to simply increase gRPC message size.
 message Payload {
   // The type of data in body.
-  optional PayloadType type = 1 [default = COMPRESSABLE];
+  PayloadType type = 1;
   // Primary contents of payload.
-  optional bytes body = 2;
+  bytes body = 2;
 }
 
 // Unary request.
 message SimpleRequest {
   // Desired payload type in the response from the server.
   // If response_type is RANDOM, server randomly chooses one from other formats.
-  optional PayloadType response_type = 1 [default = COMPRESSABLE];
+  PayloadType response_type = 1;
 
   // Desired payload size in the response from the server.
   // If response_type is COMPRESSABLE, this denotes the size before compression.
-  optional int32 response_size = 2;
+  int32 response_size = 2;
 
   // Optional input payload sent along with the request.
-  optional Payload payload = 3;
+  Payload payload = 3;
 
   // Whether SimpleResponse should include username.
-  optional bool fill_username = 4;
+  bool fill_username = 4;
 
   // Whether SimpleResponse should include OAuth scope.
-  optional bool fill_oauth_scope = 5;
+  bool fill_oauth_scope = 5;
 }
 
 // Unary response, as configured by the request.
 message SimpleResponse {
   // Payload to increase message size.
-  optional Payload payload = 1;
+  Payload payload = 1;
   // The user the request came from, for verifying authentication was
   // successful when the client expected it.
-  optional string username = 2;
+  string username = 2;
   // OAuth scope.
-  optional string oauth_scope = 3;
+  string oauth_scope = 3;
 }
 
 // Client-streaming request.
 message StreamingInputCallRequest {
   // Optional input payload sent along with the request.
-  optional Payload payload = 1;
+  Payload payload = 1;
 
   // Not expecting any payload from the response.
 }
@@ -96,18 +96,18 @@ message StreamingInputCallRequest {
 // Client-streaming response.
 message StreamingInputCallResponse {
   // Aggregated size of payloads received from the client.
-  optional int32 aggregated_payload_size = 1;
+  int32 aggregated_payload_size = 1;
 }
 
 // Configuration for a particular response.
 message ResponseParameters {
   // Desired payload sizes in responses from the server.
   // If response_type is COMPRESSABLE, this denotes the size before compression.
-  optional int32 size = 1;
+  int32 size = 1;
 
   // Desired interval between consecutive responses in the response stream in
   // microseconds.
-  optional int32 interval_us = 2;
+  int32 interval_us = 2;
 }
 
 // Server-streaming request.
@@ -116,17 +116,17 @@ message StreamingOutputCallRequest {
   // If response_type is RANDOM, the payload from each response in the stream
   // might be of different types. This is to simulate a mixed type of payload
   // stream.
-  optional PayloadType response_type = 1 [default = COMPRESSABLE];
+  PayloadType response_type = 1;
 
   // Configuration for each expected response message.
   repeated ResponseParameters response_parameters = 2;
 
   // Optional input payload sent along with the request.
-  optional Payload payload = 3;
+  Payload payload = 3;
 }
 
 // Server-streaming response, as configured by the request and parameters.
 message StreamingOutputCallResponse {
   // Payload to increase response size.
-  optional Payload payload = 1;
+  Payload payload = 1;
 }
diff --git a/src/node/interop/test.proto b/src/node/interop/test.proto
index 927a3a83aa26772075a9602012cab791071e41f8..d2c3f9befef6bf3e375062c353f16eb2266c66c8 100644
--- a/src/node/interop/test.proto
+++ b/src/node/interop/test.proto
@@ -30,7 +30,8 @@
 
 // An integration test service that covers all the method signature permutations
 // of unary/streaming requests/responses.
-syntax = "proto2";
+
+syntax = "proto3";
 
 import "empty.proto";
 import "messages.proto";
diff --git a/src/node/package.json b/src/node/package.json
index 0bb3c3d1fd07ff5fc5649f643f59334cdadcbb9c..4033bc59cf95d3779dde3c187514d4ab8032ef7e 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -26,7 +26,7 @@
   "dependencies": {
     "bindings": "^1.2.0",
     "nan": "^1.5.0",
-    "protobufjs": "^4.0.0-b2",
+    "protobufjs": "dcodeIO/ProtoBuf.js",
     "underscore": "^1.6.0",
     "underscore.string": "^3.0.0"
   },
diff --git a/src/node/test/test_service.proto b/src/node/test/test_service.proto
index 5d3d891841f5eae22b26b34de4b238be2582cdea..564169829c39dc0f49bb0fc01f0c974165e97e1c 100644
--- a/src/node/test/test_service.proto
+++ b/src/node/test/test_service.proto
@@ -27,14 +27,14 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto2";
+syntax = "proto3";
 
 message Request {
-  optional bool error = 1;
+  bool error = 1;
 }
 
 message Response {
-  optional int32 count = 1;
+  int32 count = 1;
 }
 
 service TestService {
diff --git a/src/python/README.md b/src/python/README.md
index 82bc7767322f0560d6ab7a1ac457786c5c669873..b5eea239f33273f04478f52cc4a7f95a21629225 100644
--- a/src/python/README.md
+++ b/src/python/README.md
@@ -7,7 +7,7 @@ The Python facility of gRPC.
 Status
 -------
 
-Usable with limitations, Pre-Alpha
+Usable with limitations, Alpha
 
 Prerequisites
 -----------------------
diff --git a/tools/gce_setup/cloud_prod_test.sh b/tools/gce_setup/cloud_prod_test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..94869ee9b60b526c3f30fc86eaba95107f957f61
--- /dev/null
+++ b/tools/gce_setup/cloud_prod_test.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+thisfile=$(readlink -ne "${BASH_SOURCE[0]}")
+test_case=$1
+client_vm=$2
+result=cloud_prod_result.$1
+cur=$(date "+%Y-%m-%d-%H-%M-%S") 
+log_link=https://pantheon.corp.google.com/m/cloudstorage/b/stoked-keyword-656-output/o/prod_result/$test_case/$cur
+
+main() {
+  source grpc_docker.sh
+  clients=(cxx java go ruby node csharp_mono python php)
+  for client in "${clients[@]}"
+  do
+    log_file_name=cloud_{$test_case}_{$client}.txt 
+    if grpc_cloud_prod_test $test_case $client_vm $client > /tmp/$log_file_name 2>&1
+    then
+      echo "          ['$test_case', '$client', 'prod', true, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/$result.txt
+    else
+      echo "          ['$test_case', '$client', 'prod', false, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/$result.txt
+    fi
+    gsutil cp /tmp/$log_file_name gs://stoked-keyword-656-output/prod_result/$test_case/$cur/$log_file_name
+    rm /tmp/$log_file_name
+  done
+  if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+    cat pre.html /tmp/$result.txt post.html > /tmp/$result.html
+    gsutil cp /tmp/$result.html gs://stoked-keyword-656-output/prod_result/$test_case/$cur/$result.html
+    rm /tmp/$result.txt
+    rm /tmp/$result.html
+  fi
+}
+
+set -x
+main "$@"
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index d3a7bdef285e9fe2885baf7e24171e86531ef56f..c49efbab606991bd63f68b42a7baf5bdf8c530e7 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -384,6 +384,7 @@ grpc_interop_test_args() {
   [[ -n $1 ]] && {  # client_type
     case $1 in
       cxx|go|java|node|php|python|ruby|csharp_mono)
+        grpc_client_platform='Docker'
         grpc_gen_test_cmd="grpc_interop_gen_$1_cmd"
         declare -F $grpc_gen_test_cmd >> /dev/null || {
           echo "-f: test_func for $1 => $grpc_gen_test_cmd is not defined" 1>&2
@@ -391,6 +392,11 @@ grpc_interop_test_args() {
         }
         shift
         ;;
+      csharp_dotnet)
+        grpc_client_platform='Windows'
+        grpc_gen_test_cmd="grpc_interop_gen_$1_cmd"
+        shift
+        ;;
       *)
         echo "bad client_type: $1" 1>&2
         return 1
@@ -456,6 +462,7 @@ grpc_cloud_prod_test_args() {
   [[ -n $1 ]] && {  # client_type
     case $1 in
       cxx|go|java|node|php|python|ruby|csharp_mono)
+        grpc_client_platform='Docker'
         grpc_gen_test_cmd="grpc_cloud_prod_gen_$1_cmd"
         declare -F $grpc_gen_test_cmd >> /dev/null || {
           echo "-f: test_func for $1 => $grpc_gen_test_cmd is not defined" 1>&2
@@ -463,6 +470,11 @@ grpc_cloud_prod_test_args() {
         }
         shift
         ;;
+       csharp_dotnet)
+        grpc_client_platform='Windows'
+        grpc_gen_test_cmd="grpc_cloud_prod_gen_$1_cmd"
+        shift
+        ;;
       *)
         echo "bad client_type: $1" 1>&2
         return 1
@@ -851,12 +863,23 @@ grpc_launch_servers() {
 test_runner() {
   local project_opt="--project $grpc_project"
   local zone_opt="--zone $grpc_zone"
-  local ssh_cmd="bash -l -c \"$cmd\""
-  echo "will run:"
-  echo "  $ssh_cmd"
-  echo "on $host"
   [[ $dry_run == 1 ]] && return 0  # don't run the command on a dry run
-  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
+  if [ "$grpc_client_platform" != "Windows" ]
+  then
+    echo "will run:"
+    echo "  $cmd"
+    echo "on $host"
+    gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
+  else
+    # gcloud's auto-uploading of RSA keys doesn't work for Windows VMs.
+    # So we have a linux machine that is authorized to access the Windows
+    # machine through ssh and we use gcloud auth support to logon to the proxy.
+    echo "will run:"
+    echo "  $cmd"
+    echo "on $host (through grpc-windows-proxy)"
+    gcloud compute $project_opt ssh $zone_opt stoked-keyword-656@grpc-windows-proxy --command "ssh $host '$cmd'" &
+  fi
+  #
   PID=$!
   echo "pid is $PID"
   for x in {0..5}
@@ -924,7 +947,7 @@ grpc_interop_test() {
 
   local grpc_zone grpc_project dry_run  # set by _grpc_set_project_and_zone
   #  grpc_interop_test_args
-  local test_case host grpc_gen_test_cmd grpc_server grpc_port
+  local test_case host grpc_gen_test_cmd grpc_server grpc_port grpc_client_platform
 
   # set the project zone and check that all necessary args are provided
   _grpc_set_project_and_zone -f grpc_interop_test_args "$@" || return 1
@@ -966,7 +989,7 @@ grpc_cloud_prod_test() {
 
   local grpc_zone grpc_project dry_run  # set by _grpc_set_project_and_zone
   #  grpc_cloud_prod_test_args
-  local test_case host grpc_gen_test_cmd
+  local test_case host grpc_gen_test_cmd grpc_client_platform
 
   # set the project zone and check that all necessary args are provided
   _grpc_set_project_and_zone -f grpc_cloud_prod_test_args "$@" || return 1
@@ -1431,6 +1454,18 @@ grpc_interop_gen_csharp_mono_cmd() {
   echo $the_cmd
 }
 
+# constructs the csharp-dotnet interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_interop_gen_csharp_dotnet_cmd() {
+  local set_workdir="cd /cygdrive/c/github/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug &&"
+  local test_script="./Grpc.IntegrationTesting.Client.exe --use_tls=true --use_test_ca=true";
+  local the_cmd="$set_workdir $test_script $@";
+  echo $the_cmd
+}
+
 # constructs the full dockerized csharp-mono gce=>prod interop test cmd.
 #
 # call-seq:
@@ -1446,6 +1481,20 @@ grpc_cloud_prod_gen_csharp_mono_cmd() {
   echo $the_cmd
 }
 
+# constructs the csharp-dotnet gce=>prod interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_gen_csharp_dotnet_cmd() {
+  local set_workdir="cd /cygdrive/c/github/grpc/src/csharp/Grpc.IntegrationTesting.Client/bin/Debug &&"
+  local test_script="./Grpc.IntegrationTesting.Client.exe --use_tls=true";
+  local set_certfile="SSL_CERT_FILE=/cacerts/roots.pem "
+  local gfe_flags=$(_grpc_prod_gfe_flags);
+  local the_cmd="$set_workdir $set_certfile $test_script $gfe_flags $@";
+  echo $the_cmd
+}
+
 # constructs the full dockerized csharp-mono service_account auth interop test cmd.
 #
 # call-seq:
diff --git a/tools/gce_setup/interop_test.sh b/tools/gce_setup/interop_test.sh
new file mode 100755
index 0000000000000000000000000000000000000000..037b117e1aada76fa84c8e818758d38c28ae235e
--- /dev/null
+++ b/tools/gce_setup/interop_test.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+thisfile=$(readlink -ne "${BASH_SOURCE[0]}")
+test_case=$1
+client_vm=$2
+server_vm=$3
+result=interop_result.$1
+cur=$(date "+%Y-%m-%d-%H-%M-%S") 
+log_link=https://pantheon.corp.google.com/m/cloudstorage/b/stoked-keyword-656-output/o/interop_result/$test_case/$cur
+
+main() {
+  source grpc_docker.sh
+  clients=(cxx java go ruby node csharp_mono python php)
+  servers=(cxx java go ruby node python csharp_mono)
+  for client in "${clients[@]}"
+  do
+    for server in "${servers[@]}"
+    do
+      log_file_name=cloud_{$test_case}_{$client}_{$server}.txt 
+      if grpc_interop_test $test_case $client_vm $client $server_vm $server> /tmp/$log_file_name 2>&1
+      then
+        echo "          ['$test_case', '$client', '$server', true, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/$result.txt
+      else
+        echo "          ['$test_case', '$client', '$server', false, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/$result.txt
+      fi
+      gsutil cp /tmp/$log_file_name gs://stoked-keyword-656-output/interop_result/$test_case/$cur/$log_file_name
+      rm /tmp/$log_file_name
+    done
+  done
+  if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
+    cat pre.html /tmp/$result.txt post.html > /tmp/$result.html
+    gsutil cp /tmp/$result.html gs://stoked-keyword-656-output/interop_result/$test_case/$cur/$result.html
+    rm /tmp/$result.txt
+    rm /tmp/$result.html
+  fi
+}
+
+set -x
+main "$@"
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index b8b4cf0001a8883cd305d08f949c013f3693d1ef..286b81dc3e3bb72404630d995d7180f5bebd951d 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -212,7 +212,9 @@ class Job(object):
         if self._bin_hash:
           update_cache.finished(self._spec.identity(), self._bin_hash)
     elif self._state == _RUNNING and time.time() - self._start > 300:
-      message('TIMEOUT', self._spec.shortname, do_newline=True)
+      self._tempfile.seek(0)
+      stdout = self._tempfile.read()
+      message('TIMEOUT', self._spec.shortname, stdout, do_newline=True)
       self.kill()
     return self._state