Home | History | Annotate | Download | only in devcycle
      1 .. _devcycle-debugging:
      2 
      3 #########
      4 Debugging
      5 #########
      6 
      7 This document describes tools and techniques you can use to debug, monitor,
      8 and measure your application's performance.
      9 
     10 .. contents:: Table Of Contents
     11   :local:
     12   :backlinks: none
     13   :depth: 3
     14 
     15 Diagnostic information
     16 ======================
     17 
     18 Viewing process statistics with the task manager
     19 ------------------------------------------------
     20 
     21 You can use Chrome's Task Manager to display information about a Native Client
     22 application:
     23 
     24 #. Open the Task Manager by clicking the menu icon |menu-icon| and choosing
     25    **Tools > Task manager**.
     26 #. When the Task Manager window appears, verify that the columns displaying
     27    memory information are visible. If they are not, right click in the header
     28    row and select the memory items from the popup menu that appears.
     29 
     30 A browser window running a Native Client application will have at least two
     31 processes associated with it: a process for the app's top level (the render
     32 process managing the page including its HTML and any JavaScript) and one or
     33 more processes for each instance of a Native Client module embedded in the page
     34 (each process running native code from one nexe file). The top-level process
     35 appears with the application's icon and begins with the text "App:". A Native
     36 Client process appears with a Chrome extension icon (a jigsaw puzzle piece
     37 |puzzle|) and begins with the text "Native Client module" followed by the URL
     38 of its manifest file.
     39 
     40 From the Task Manager you can view the changing memory allocations of all the
     41 processes associated with a Native Client application. Each process has its own
     42 memory footprint. You can also see the rendering rate displayed as frames per
     43 second (FPS). Note that the computation of render frames can be performed in
     44 any process, but the rendering itself is always done in the top level
     45 application process, so look for the rendering rate there.
     46 
     47 Controlling the level of Native Client error and warning messages
     48 -----------------------------------------------------------------
     49 
     50 Native Client prints warning and error messages to stdout and stderr. You can
     51 increase the amount of Native Client's diagnostic output by setting the
     52 following `environment variables
     53 <http://en.wikipedia.org/wiki/Environment_variable>`_:
     54 
     55 * NACL_DEBUG_ENABLE=1
     56 * PPAPI_BROWSER_DEBUG=1
     57 * NACL_PLUGIN_DEBUG=1
     58 * NACL_PPAPI_PROXY_DEBUG=1
     59 * NACL_SRPC_DEBUG=[1-255] (use a higher number for more verbose debug output)
     60 * NACLVERBOSITY=[1-255]
     61 
     62 Basic debugging
     63 ===============
     64 
     65 Writing messages to the JavaScript console
     66 ------------------------------------------
     67 
     68 You can send messages from your C/C++ code to JavaScript using the PostMessage
     69 call in the :doc:`Pepper messaging system <../coding/message-system>`. When the
     70 JavaScript code receives a message, its message event handler can call
     71 `console.log() <https://developer.mozilla.org/en/DOM/console.log>`_ to write
     72 the message to the JavaScript `console </devtools/docs/console-api>`_ in
     73 Chrome's Developer Tools.
     74 
     75 Debugging with printf
     76 ---------------------
     77 
     78 Your C/C++ code can perform inline printf debugging to stdout and stderr by
     79 calling fprintf() directly, or by using cover functions like these:
     80 
     81 .. naclcode::
     82 
     83   #include <stdio.h>
     84   void logmsg(const char* pMsg){
     85     fprintf(stdout,"logmsg: %s\n",pMsg);
     86   }
     87   void errormsg(const char* pMsg){
     88     fprintf(stderr,"logerr: %s\n",pMsg);
     89   }
     90 
     91 By default stdout and stderr will appear in Chrome's stdout and stderr stream
     92 but they can also be redirected as described below.
     93 
     94 Redirecting output to log files
     95 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     96 
     97 You can redirect stdout and stderr to output files by setting these environment variables:
     98 
     99 * ``NACL_EXE_STDOUT=c:\nacl_stdout.log``
    100 * ``NACL_EXE_STDERR=c:\nacl_stderr.log``
    101 
    102 There is another variable, ``NACLLOG``, that you can use to redirect Native
    103 Client's internally-generated messages. This variable is set to stderr by
    104 default; you can redirect these messages to an output file by setting the
    105 variable as follows:
    106 
    107 * ``NACLLOG=c:\nacl.log``
    108 
    109 .. Note::
    110   :class: note
    111 
    112   **Note:** If you set the NACL_EXE_STDOUT, NACL_EXE_STDERR, or NACLLOG
    113   variables to redirect output to a file, you must run Chrome with the
    114   ``--no-sandbox`` flag.  You must also be careful that each variable points to
    115   a different file.
    116 
    117 Redirecting output to the JavaScript console
    118 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    119 
    120 You can also cause output from printf statements in your C/C++ code to be
    121 relayed to the JavaScript side of your application through the Pepper messaging
    122 system, where you can then write the output to the JavaScript console. Follow
    123 these steps:
    124 
    125 #. Set the NACL_EXE_STDOUT and NACL_EXE_STDERR environment variables as
    126    follows:
    127 
    128    * NACL_EXE_STDOUT=DEBUG_ONLY:dev://postmessage
    129    * NACL_EXE_STDERR=DEBUG_ONLY:dev://postmessage
    130 
    131    These settings tell Native Client to use PostMessage() to send output that
    132    your Native Client module writes to stdout and stderr to the JavaScript side
    133    of your application.
    134 
    135 #. Register a JavaScript handler to receive messages from your Native Client
    136    module:
    137 
    138    .. naclcode::
    139 
    140      <div id="nacl_container">
    141        <script type="text/javascript">
    142          var container = document.getElementById('nacl_container');
    143          container.addEventListener('message', handleMessage, true);
    144        </script>
    145        <embed id="nacl_module"
    146               src="my_application.nmf"
    147               type="application/x-nacl" />
    148      </div>
    149 
    150 #. Implement a simple JavaScript handler that logs the messages it receives to
    151    the JavaScript console:
    152 
    153    .. naclcode::
    154 
    155      function handleMessage(message_event) {
    156        console.log(message_event.data);
    157      }
    158 
    159    This handler works in the simple case where the only messages your Native
    160    Client module sends to JavaScript are messages with the output from stdout
    161    and stderr. If your Native Client module also sends other messages to
    162    JavaScript, your handler will need to be more complex.
    163 
    164    Once you've implemented a message handler and set up the environment
    165    variables as described above, you can check the JavaScript console to see
    166    output that your Native Client module prints to stdout and stderr. Keep in
    167    mind that your module makes a call to PostMessage() every time it flushes
    168    stdout or stderr.  Your application's performance will degrade considerably
    169    if your module prints and flushes frequently, or if it makes frequent Pepper
    170    calls to begin with (e.g., to render).
    171 
    172 Logging calls to Pepper interfaces
    173 ----------------------------------
    174 
    175 You can log all Pepper calls your module makes by passing the following flags
    176 to Chrome on startup::
    177 
    178   --vmodule=ppb*=4 --enable-logging=stderr
    179 
    180 
    181 The ``vmodule`` flag tells Chrome to log all calls to C Pepper interfaces that
    182 begin with "ppb" (that is, the interfaces that are implemented by the browser
    183 and that your module calls). The ``enable-logging`` flag tells Chrome to log
    184 the calls to stderr.
    185 
    186 .. _visual_studio:
    187 
    188 Debugging with Visual Studio
    189 ----------------------------
    190 
    191 If you develop on a Windows platform you can use the :doc:`Native Client Visual
    192 Studio add-in <vs-addin>` to write and debug your code. The add-in defines new
    193 project platforms that let you run your module in two different modes: As a
    194 Pepper plugin and as a Native Client module. When running as a Pepper plugin
    195 you can use the built-in Visual Studio debugger. When running as a Native
    196 Client module Visual Studio will launch an instance of nacl-gdb for you and
    197 link it to the running code.
    198 
    199 .. _using_gdb:
    200 
    201 Debugging with nacl-gdb
    202 -----------------------
    203 
    204 The Native Client SDK includes a command-line debugger that you can use to
    205 debug Native Client modules. The debugger is based on the GNU debugger `gdb
    206 <http://www.gnu.org/software/gdb/>`_, and is located at
    207 ``toolchain/<platform>_x86_newlib/bin/x86_64-nacl-gdb`` (where *<platform>*
    208 is the platform of your development machine: ``win``, ``mac``, or
    209 ``linux``).
    210 
    211 Note that this same copy of GDB can be used to debug any NaCl program,
    212 whether built using newlib or glibc for x86-32, x86-64 or ARM.  In the SDK,
    213 ``i686-nacl-gdb`` is an alias for ``x86_64-nacl-gdb``, and the ``newlib``
    214 and ``glibc`` toolchains both contain the same version of GDB.
    215 
    216 .. _debugging_pnacl_pexes:
    217 
    218 Debugging PNaCl pexes (with Pepper 35+)
    219 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    220 
    221 If you want to use GDB to debug a program that is compiled with the PNaCl
    222 toolchain, you must have a copy of the pexe from **before** running
    223 ``pnacl-finalize``. The ``pnacl-finalize`` tool converts LLVM bitcode
    224 to the stable PNaCl bitcode format, but it also strips out debug
    225 metadata, which we need for debugging. In this section we'll give the
    226 LLVM bitcode file a ``.bc`` file extension, and the PNaCl bitcode file
    227 a ``.pexe`` file extension. The actual extension should not matter, but
    228 it helps distinguish between the two types of files.
    229 
    230 **Note** unlike the finalized copy of the pexe, the non-finalized debug copy
    231 is not considered stable. This means that a debug copy of the PNaCl
    232 application created by a Pepper N SDK is only guaranteed to run
    233 with a matching Chrome version N. If the version of the debug bitcode pexe
    234 does not match that of Chrome then the translation process may fail, and
    235 you will see and error message in the JavaScript console.
    236 
    237 Also, make sure you are passing the ``-g`` :ref:`compile option
    238 <compile_flags>` to ``pnacl-clang`` to enable generating debugging info.
    239 You might also want to omit ``-O2`` from the compile-time and link-time
    240 options, otherwise GDB not might be able to print variables' values when
    241 debugging (this is more of a problem with the PNaCl/LLVM toolchain than
    242 with GCC).
    243 
    244 Once you have built a non-stable debug copy of the pexe, list the URL of
    245 that copy in your application's manifest file:
    246 
    247 .. naclcode::
    248 
    249   {
    250     "program": {
    251       "pnacl-translate": {
    252         "url": "release_version.pexe",
    253         "optlevel": 2
    254       },
    255       "pnacl-debug": {
    256         "url": "debug_version.bc",
    257         "optlevel": 0
    258       }
    259     }
    260   }
    261 
    262 Copy the ``debug_version.bc`` and ``nmf`` files to the location that
    263 your local web server serves files from.
    264 
    265 When you run Chrome with ``--enable-nacl-debug``, Chrome will translate
    266 and run the ``debug_version.bc`` instead of ``release_version.pexe``.
    267 Once the debug version is loaded, you are ready to :ref:`run nacl-gdb
    268 <running_nacl_gdb>`
    269 
    270 Whether you publish the NMF file containing the debug URL to the release
    271 web server, is up to you. One reason to avoid publishing the debug URL
    272 is that it is only guaranteed to work for the Chrome version that matches
    273 the SDK version. Developers who may have left the ``--enable-nacl-debug``
    274 flag turned on may end up loading the debug copy of your application
    275 (which may or may not work, depending on their version of Chrome).
    276 
    277 
    278 Debugging PNaCl pexes (with older Pepper toolchains)
    279 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    280 
    281 If you want to use GDB to debug a program that is compiled with the PNaCl
    282 toolchain, you must convert the ``pexe`` file to a ``nexe``.  (You can skip
    283 this step if you are using the GCC toolchain, or if you are using
    284 pepper 35 or later.)
    285 
    286 * Firstly, make sure you are passing the ``-g`` :ref:`compile option
    287   <compile_flags>` to ``pnacl-clang`` to enable generating debugging info.
    288   You might also want to omit ``-O2`` from the compile-time and link-time
    289   options.
    290 
    291 * Secondly, use ``pnacl-translate`` to convert your ``pexe`` to one or more
    292   ``nexe`` files.  For example:
    293 
    294   .. naclcode::
    295     :prettyprint: 0
    296 
    297     <NACL_SDK_ROOT>/toolchain/win_pnacl/bin/pnacl-translate ^
    298       --allow-llvm-bitcode-input hello_world.pexe -arch x86-32 -o hello_world_x86_32.nexe
    299     <NACL_SDK_ROOT>/toolchain/win_pnacl/bin/pnacl-translate ^
    300       --allow-llvm-bitcode-input hello_world.pexe -arch x86-64 -o hello_world_x86_64.nexe
    301 
    302   For this, use the non-finalized ``pexe`` file produced by
    303   ``pnacl-clang``, not the ``pexe`` file produced by ``pnacl-finalize``.
    304   The latter ``pexe`` has debugging info stripped out.  The option
    305   ``--allow-llvm-bitcode-input`` tells ``pnacl-translate`` to accept a
    306   non-finalized ``pexe``.
    307 
    308 * Replace the ``nmf`` :ref:`manifest file <manifest_file>` that points to
    309   your ``pexe`` file with one that points to the ``nexe`` files.  For the
    310   example ``nexe`` filenames above, the new ``nmf`` file would contain:
    311 
    312   .. naclcode::
    313     :prettyprint: 0
    314 
    315     {
    316       "program": {
    317         "x86-32": {"url": "hello_world_x86_32.nexe"},
    318         "x86-64": {"url": "hello_world_x86_64.nexe"},
    319       }
    320     }
    321 
    322 * Change the ``<embed>`` HTML element to use
    323   ``type="application/x-nacl"`` rather than
    324   ``type="application/x-pnacl"``.
    325 
    326 * Copy the ``nexe`` and ``nmf`` files to the location that your local web
    327   server serves files from.
    328 
    329 .. Note::
    330   :class: note
    331 
    332   **Note:** If you know whether Chrome is using the x86-32 or x86-64
    333   version of the NaCl sandbox on your system, you can translate the
    334   ``pexe`` once to a single x86-32 or x86-64 ``nexe``.  Otherwise, you
    335   might find it easier to translate the ``pexe`` to both ``nexe``
    336   formats as described above.
    337 
    338 .. _running_nacl_gdb:
    339 
    340 Running nacl-gdb
    341 ~~~~~~~~~~~~~~~~
    342 
    343 Before you start using nacl-gdb, make sure you can :doc:`build <building>` your
    344 module and :doc:`run <running>` your application normally. This will verify
    345 that you have created all the required :doc:`application parts
    346 <../coding/application-structure>` (.html, .nmf, and .nexe files, shared
    347 libraries, etc.), that your server can access those resources, and that you've
    348 configured Chrome correctly to run your application.  The instructions below
    349 assume that you are using a :ref:`local server <web_server>` to run your
    350 application; one benefit of doing it this way is that you can check the web
    351 server output to confirm that your application is loading the correct
    352 resources. However, some people prefer to run their application as an unpacked
    353 extension, as described in :doc:`Running Native Client Applications <running>`.
    354 
    355 Follow the instructions below to debug your module with nacl-gdb:
    356 
    357 #. Compile your module with the ``-g`` flag so that your .nexe retains symbols
    358    and other debugging information (see the :ref:`recommended compile flags
    359    <compile_flags>`).
    360 #. Launch a local web server (e.g., the :ref:`web server <web_server>` included
    361    in the SDK).
    362 #. Launch Chrome with these three required flags: ``--enable-nacl --enable-nacl-debug --no-sandbox``.
    363 
    364    You may also want to use some of the optional flags listed below. A typical
    365    command looks like this::
    366 
    367      chrome --enable-nacl --enable-nacl-debug --no-sandbox --disable-hang-monitor localhost:5103
    368 
    369    **Required flags:**
    370 
    371    ``--enable-nacl``
    372      Enables Native Client for all applications, including those that are
    373      launched outside the Chrome Web Store.
    374 
    375    ``--enable-nacl-debug``
    376      Turns on the Native Client debug stub, opens TCP port 4014, and pauses
    377      Chrome to let the debugger connect.
    378 
    379    ``--no-sandbox``
    380      Turns off the Chrome sandbox (not the Native Client sandbox). This enables
    381      the stdout and stderr streams, and lets the debugger connect.
    382 
    383    **Optional flags:**
    384 
    385    ``--disable-hang-monitor``
    386      Prevents Chrome from displaying a warning when a tab is unresponsive.
    387 
    388    ``--user-data-dir=<directory>``
    389      Specifies the `user data directory
    390      <http://www.chromium.org/user-experience/user-data-directory>`_ from which
    391      Chrome should load its state.  You can specify a different user data
    392      directory so that changes you make to Chrome in your debugging session do
    393      not affect your personal Chrome data (history, cookies, bookmarks, themes,
    394      and settings).
    395 
    396    ``--nacl-debug-mask=<nmf_url_mask1,nmf_url_mask2,...>``
    397      Specifies a set of debug mask patterns. This allows you to selectively
    398      choose to debug certain applications and not debug others. For example, if
    399      you only want to debug the NMF files for your applications at
    400      ``https://example.com/app``, and no other NaCl applications found on the
    401      web, specify ``--nacl-debug-mask=https://example.com/app/*.nmf``.  This
    402      helps prevent accidentally debugging other NaCl applications if you like
    403      to leave the ``--enable-nacl-debug`` flag turned on.  The pattern language
    404      for the mask follows `chrome extension match patterns
    405      </extensions/match_patterns>`_.  The pattern set can be inverted by
    406      prefixing the pattern set with the ``!`` character.
    407 
    408    ``<URL>``
    409      Specifies the URL Chrome should open when it launches. The local server
    410      that comes with the SDK listens on port 5103 by default, so the URL when
    411      you're debugging is typically ``localhost:5103`` (assuming that your
    412      application's page is called index.html and that you run the local server
    413      in the directory where that page is located).
    414 
    415 #. Navigate to your application's page in Chrome. (You don't need to do this if
    416    you specified a URL when you launched Chrome in the previous step.) Chrome
    417    will start loading the application, then pause and wait until you start
    418    nacl-gdb and run the ``continue`` command.
    419 
    420 #. Go to the directory with your source code, and run nacl-gdb from there. For
    421    example::
    422 
    423      cd <NACL_SDK_ROOT>/examples/hello_world_gles
    424      <NACL_SDK_ROOT>/toolchain/win_x86_newlib/bin/x86_64-nacl-gdb
    425 
    426    The debugger will start and show you a gdb prompt::
    427 
    428      (gdb)
    429 
    430 #. For debugging PNaCl pexes run the following gdb command lines
    431    (skip to the next item if you are using NaCl instead of PNaCl)::
    432 
    433      (gdb) target remote localhost:4014
    434      (gdb) remote get nexe <path-to-save-translated-nexe-with-debug-info>
    435      (gdb) file <path-to-save-translated-nexe-with-debug-info>
    436      (gdb) remote get irt <path-to-save-NaCl-integrated-runtime>
    437      (gdb) nacl-irt <path-to-saved-NaCl-integrated-runtime>
    438 
    439 #. For NaCl nexes, run the following commands from the gdb command line::
    440 
    441      (gdb) target remote localhost:4014
    442      (gdb) nacl-manifest <path-to-your-.nmf-file>
    443      (gdb) remote get irt <path-to-save-NaCl-integrated-runtime>
    444      (gdb) nacl-irt <path-to-saved-NaCl-integrated-runtime>
    445 
    446 #. The command used for PNaCl and NaCl are described below:
    447 
    448    ``target remote localhost:4014``
    449      Tells the debugger how to connect to the debug stub in the Native Client
    450      application loader. This connection occurs through TCP port 4014 (note
    451      that this port is distinct from the port which the local web server uses
    452      to listen for incoming requests, typically port 5103). If you are
    453      debugging multiple applications at the same time, the loader may choose
    454      a port that is different from the default 4014 port. See the Chrome
    455      task manager for the debug port.
    456 
    457    ``remote get nexe <path>``
    458      This saves the application's main executable (nexe) to ``<path>``.
    459      For PNaCl, this provides a convenient way to access the nexe that is
    460      a **result** of translating your pexe. This can then be loaded with
    461      the ``file <path>`` command.
    462 
    463    ``nacl-manifest <path>``
    464      For NaCl (not PNaCl), this tells the debugger where to find your
    465      application's executable (.nexe) files. The application's manifest
    466      (.nmf) file lists your application's executable files, as well as any
    467      libraries that are linked with the application dynamically.
    468 
    469    ``remote get irt <path>``
    470      This saves the Native Client Integrated Runtime (IRT). Normally,
    471      the IRT is located in the same directory as the Chrome executable,
    472      or in a subdirectory named after the Chrome version. For example, if
    473      you're running Chrome canary on Windows, the path to the IRT typically
    474      looks something like ``C:/Users/<username>/AppData/Local/Google/Chrome
    475      SxS/Application/23.0.1247.1/nacl_irt_x86_64.nexe``.
    476      The ``remote get irt <path>`` saves that to the current working
    477      directory so that you do not need to find where exactly the IRT
    478      is stored alongside Chrome.
    479 
    480    ``nacl-irt <path>``
    481      Tells the debugger where to find the Native Client Integrated Runtime
    482      (IRT). ``<path>`` can either be the location of the copy saved by
    483      ``remote get irt <path>`` or the copy that is installed alongside Chrome.
    484 
    485    A couple of notes on how to specify path names in the nacl-gdb commands
    486    above:
    487 
    488    * You can use a forward slash to separate directories on Linux, Mac, and
    489      Windows. If you use a backslash to separate directories on Windows, you
    490      must escape the backslash by using a double backslash "\\" between
    491      directories.
    492    * If any directories in the path have spaces in their name, you must put
    493      quotation marks around the path.
    494 
    495    As an example, here is a what these nacl-gdb commands might look like on
    496    Windows::
    497 
    498      target remote localhost:4014
    499      nacl-manifest "C:/<NACL_SDK_ROOT>/examples/hello_world_gles/newlib/Debug/hello_world_gles.nmf"
    500      nacl-irt "C:/Users/<username>/AppData/Local/Google/Chrome SxS/Application/23.0.1247.1/nacl_irt_x86_64.nexe"
    501 
    502    To save yourself some typing, you can put put these nacl-gdb commands in a
    503    script file, and execute the file when you run nacl-gdb, like so::
    504 
    505      <NACL_SDK_ROOT>/toolchain/win_x86_newlib/bin/x86_64-nacl-gdb -x <nacl-script-file>
    506 
    507    If nacl-gdb connects successfully to Chrome, it displays a message such as
    508    the one below, followed by a gdb prompt::
    509 
    510      0x000000000fc00200 in _start ()
    511      (gdb)
    512 
    513    If nacl-gdb can't connect to Chrome, it displays a message such as
    514    "``localhost:4014: A connection attempt failed``" or "``localhost:4014:
    515    Connection timed out.``" If you see a message like that, make sure that you
    516    have launched a web server, launched Chrome, and navigated to your
    517    application's page before starting nacl-gdb.
    518 
    519 Once nacl-gdb connects to Chrome, you can run standard gdb commands to execute
    520 your module and inspect its state. Some commonly used commands are listed
    521 below.
    522 
    523 ``break <location>``
    524   set a breakpoint at <location>, e.g.::
    525 
    526     break hello_world.cc:79
    527     break hello_world::HelloWorldInstance::HandleMessage
    528     break Render
    529 
    530 ``continue``
    531   resume normal execution of the program
    532 
    533 ``next``
    534   execute the next source line, stepping over functions
    535 
    536 ``step``
    537   execute the next source line, stepping into functions
    538 
    539 ``print <expression>``
    540   print the value of <expression> (e.g., variables)
    541 
    542 ``backtrace``
    543   print a stack backtrace
    544 
    545 ``info breakpoints``
    546   print a table of all breakpoints
    547 
    548 ``delete <breakpoint>``
    549   delete the specified breakpoint (you can use the breakpoint number displayed
    550   by the info command)
    551 
    552 ``help <command>``
    553   print documentation for the specified gdb <command>
    554 
    555 ``quit``
    556   quit gdb
    557 
    558 See the `gdb documentation
    559 <http://sourceware.org/gdb/current/onlinedocs/gdb/#toc_Top>`_ for a
    560 comprehensive list of gdb commands. Note that you can abbreviate most commands
    561 to just their first letter (``b`` for break, ``c`` for continue, and so on).
    562 
    563 To interrupt execution of your module, press <Ctrl-c>. When you're done
    564 debugging, close the Chrome window and type ``q`` to quit gdb.
    565 
    566 Debugging with other tools
    567 ==========================
    568 
    569 If you cannot use the :ref:`Visual Studio add-in <visual_studio>`, or you want
    570 to use a debugger other than nacl-gdb, you must manually build your module as a
    571 Pepper plugin (sometimes referred to as a "`trusted
    572 <http://www.chromium.org/nativeclient/getting-started/getting-started-background-and-basics#TOC-Trusted-vs-Untrusted>`_"
    573 or "in-process" plugin).  Pepper plugins (.DLL files on Windows; .so files on
    574 Linux; .bundle files on Mac) are loaded directly in either the Chrome renderer
    575 process or a separate plugin process, rather than in Native Client. Building a
    576 module as a trusted Pepper plugin allows you to use standard debuggers and
    577 development tools on your system, but when you're finished developing the
    578 plugin, you need to port it to Native Client (i.e., build the module with one
    579 of the toolchains in the NaCl SDK so that the module runs in Native Client).
    580 For details on this advanced development technique, see `Debugging a Trusted
    581 Plugin
    582 <http://www.chromium.org/nativeclient/how-tos/debugging-documentation/debugging-a-trusted-plugin>`_.
    583 Note that starting with the ``pepper_22`` bundle, the NaCl SDK for Windows
    584 includes pre-built libraries and library source code, making it much easier to
    585 build a module into a .DLL.
    586 
    587 Open source profiling tools
    588 ---------------------------
    589 
    590 For the brave-hearted there are open source tools at `Chromium.org
    591 <http://www.chromium.org/nativeclient>`_ that describe how to do profiling on
    592 `64-bit Windows
    593 <https://sites.google.com/a/chromium.org/dev/nativeclient/how-tos/profiling-nacl-apps-on-64-bit-windows>`_
    594 and `Linux
    595 <http://www.chromium.org/nativeclient/how-tos/limited-profiling-with-oprofile-on-x86-64>`_
    596 machines.
    597 
    598 
    599 .. |menu-icon| image:: /images/menu-icon.png
    600 .. |puzzle| image:: /images/puzzle.png
    601