LCOV - code coverage report
Current view: directory - src/trusted/debug_stub - nacl_debug.cc (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 55 43 78.2 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : 
       8                 : #include <vector>
       9                 : #include <map>
      10                 : 
      11                 : /*
      12                 :  * NaCl Functions for intereacting with debuggers
      13                 :  */
      14                 : 
      15                 : #include "native_client/src/include/nacl_string.h"
      16                 : #include "native_client/src/shared/platform/nacl_check.h"
      17                 : #include "native_client/src/shared/platform/nacl_exit.h"
      18                 : #include "native_client/src/shared/platform/nacl_log.h"
      19                 : #include "native_client/src/shared/platform/nacl_threads.h"
      20                 : #include "native_client/src/trusted/debug_stub/debug_stub.h"
      21                 : #include "native_client/src/trusted/debug_stub/platform.h"
      22                 : #include "native_client/src/trusted/debug_stub/session.h"
      23                 : #include "native_client/src/trusted/debug_stub/target.h"
      24                 : #include "native_client/src/trusted/debug_stub/thread.h"
      25                 : #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
      26                 : #include "native_client/src/trusted/service_runtime/nacl_debug_init.h"
      27                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      28                 : #include "native_client/src/trusted/service_runtime/thread_suspension.h"
      29                 : 
      30                 : using port::IPlatform;
      31                 : using port::IThread;
      32                 : using port::ITransport;
      33                 : using port::SocketBinding;
      34                 : 
      35                 : using gdb_rsp::Session;
      36                 : using gdb_rsp::Target;
      37                 : 
      38                 : #if NACL_WINDOWS
      39                 : /* Disable warning for unwind disabled when exceptions used */
      40                 : #pragma warning(disable:4530)
      41                 : #endif
      42                 : 
      43                 : 
      44                 : static Target *g_target = NULL;
      45                 : static SocketBinding *g_socket_binding = NULL;
      46                 : 
      47                 : int NaClDebugBindSocket() {
      48              34 :   if (g_socket_binding == NULL) {
      49              17 :     NaClDebugStubInit();
      50                 :     // Try port 4014 first for compatibility.
      51              17 :     g_socket_binding = SocketBinding::Bind("127.0.0.1:4014");
      52                 :     // If port 4014 is not available, try any port.
      53              17 :     if (g_socket_binding == NULL) {
      54               0 :       g_socket_binding = SocketBinding::Bind("127.0.0.1:0");
      55               0 :     }
      56              17 :     if (g_socket_binding == NULL) {
      57               0 :       NaClLog(LOG_ERROR,
      58                 :               "NaClDebugStubBindSocket: Failed to bind any TCP port\n");
      59               0 :       return 0;
      60                 :     }
      61              17 :     NaClLog(LOG_WARNING,
      62                 :             "nacl_debug(%d) : Connect GDB with 'target remote :%d\n",
      63              17 :             __LINE__, g_socket_binding->GetBoundPort());
      64              17 :   }
      65              34 :   return 1;
      66              34 : }
      67                 : 
      68               0 : void NaClDebugSetBoundSocket(NaClSocketHandle bound_socket) {
      69               0 :   CHECK(g_socket_binding == NULL);
      70               0 :   g_socket_binding = new SocketBinding(bound_socket);
      71               0 : }
      72                 : 
      73              17 : void WINAPI NaClStubThread(void *thread_arg) {
      74              34 :   UNREFERENCED_PARAMETER(thread_arg);
      75                 : 
      76              17 :   while (1) {
      77                 :     // Wait for a connection.
      78              29 :     nacl::scoped_ptr<ITransport> trans(g_socket_binding->AcceptConnection());
      79              58 :     if (NULL == trans.get()) continue;
      80                 : 
      81                 :     // Create a new session for this connection
      82              58 :     Session ses(trans.get());
      83              29 :     ses.SetFlags(Session::DEBUG_MASK);
      84                 : 
      85              29 :     NaClLog(LOG_WARNING, "nacl_debug(%d) : Connected, happy debugging!\n",
      86                 :             __LINE__);
      87                 : 
      88                 :     // Run this session for as long as it lasts
      89              14 :     g_target->Run(&ses);
      90              70 :   }
      91               0 : }
      92                 : 
      93              20 : static void ThreadCreateHook(struct NaClAppThread *natp) throw() {
      94              20 :   g_target->TrackThread(natp);
      95              20 : }
      96                 : 
      97               3 : static void ThreadExitHook(struct NaClAppThread *natp) throw() {
      98               3 :   g_target->IgnoreThread(natp);
      99               3 : }
     100                 : 
     101                 : static void ProcessExitHook() throw() {
     102               2 :   g_target->Exit();
     103               2 :   NaClDebugStubFini();
     104               2 : }
     105                 : 
     106                 : static const struct NaClDebugCallbacks debug_callbacks = {
     107                 :   ThreadCreateHook,
     108                 :   ThreadExitHook,
     109                 :   ProcessExitHook,
     110                 : };
     111                 : 
     112                 : /*
     113                 :  * This function is implemented for the service runtime.  The service runtime
     114                 :  * declares the function so it does not need to be declared in our header.
     115                 :  */
     116              17 : int NaClDebugInit(struct NaClApp *nap) {
     117              17 :   if (!NaClFaultedThreadQueueEnable(nap)) {
     118               0 :     NaClLog(LOG_ERROR, "NaClDebugInit: Failed to initialize fault handling\n");
     119               0 :     return 0;
     120                 :   }
     121              17 :   nap->debug_stub_callbacks = &debug_callbacks;
     122                 : 
     123              51 :   CHECK(g_target == NULL);
     124              34 :   g_target = new Target(nap);
     125              51 :   CHECK(g_target != NULL);
     126              17 :   g_target->Init();
     127                 : 
     128              17 :   if (!NaClDebugBindSocket()) {
     129               0 :     return 0;
     130                 :   }
     131                 : #if NACL_WINDOWS
     132                 :   nap->debug_stub_port = g_socket_binding->GetBoundPort();
     133                 : #endif
     134                 : 
     135              17 :   NaClThread *thread = new NaClThread;
     136              51 :   CHECK(thread != NULL);
     137                 : 
     138              17 :   NaClLog(LOG_WARNING, "nacl_debug(%d) : Debugging started.\n", __LINE__);
     139              51 :   CHECK(NaClThreadCtor(thread, NaClStubThread, NULL, NACL_KERN_STACK_SIZE));
     140                 : 
     141              17 :   return 1;
     142              17 : }

Generated by: LCOV version 1.7