- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / doc / devguide / devcycle / debugging.rst
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: 2
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
73 <https://developers.google.com/chrome-developer-tools/docs/console>`_ in
74 Chrome's Developer Tools.
75
76 Debugging with printf
77 ---------------------
78
79 Your C/C++ code can perform inline printf debugging to stdout and stderr by
80 calling fprintf() directly, or by using cover functions like these:
81
82 .. naclcode::
83
84   #include <stdio.h>
85   void logmsg(const char* pMsg){
86     fprintf(stdout,"logmsg: %s\n",pMsg);
87   }
88   void errormsg(const char* pMsg){
89     fprintf(stderr,"logerr: %s\n",pMsg);
90   }
91
92 By default stdout and stderr will appear in Chrome's stdout and stderr stream
93 but they can also be redirected as described below.
94
95 Redirecting output to log files
96 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
97
98 You can redirect stdout and stderr to output files by setting these environment variables:
99
100 * ``NACL_EXE_STDOUT=c:\nacl_stdout.log``
101 * ``NACL_EXE_STDERR=c:\nacl_stderr.log``
102
103 There is another variable, ``NACLLOG``, that you can use to redirect Native
104 Client's internally-generated messages. This variable is set to stderr by
105 default; you can redirect these messages to an output file by setting the
106 variable as follows:
107
108 * ``NACLLOG=c:\nacl.log``
109
110 .. Note::
111   :class: note
112
113   **Note:** If you set the NACL_EXE_STDOUT, NACL_EXE_STDERR, or NACLLOG
114   variables to redirect output to a file, you must run Chrome with the
115   ``--no-sandbox`` flag.  You must also be careful that each variable points to
116   a different file.
117
118 Redirecting output to the JavaScript console
119 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
120
121 You can also cause output from printf statements in your C/C++ code to be
122 relayed to the JavaScript side of your application through the Pepper messaging
123 system, where you can then write the output to the JavaScript console. Follow
124 these steps:
125
126 #. Set the NACL_EXE_STDOUT and NACL_EXE_STDERR environment variables as
127    follows:
128
129    * NACL_EXE_STDOUT=DEBUG_ONLY:dev://postmessage
130    * NACL_EXE_STDERR=DEBUG_ONLY:dev://postmessage
131
132    These settings tell Native Client to use PostMessage() to send output that
133    your Native Client module writes to stdout and stderr to the JavaScript side
134    of your application.
135
136 #. Register a JavaScript handler to receive messages from your Native Client
137    module:
138
139    .. naclcode::
140
141      <div id="nacl_container">
142        <script type="text/javascript">
143          var container = document.getElementById('nacl_container');
144          container.addEventListener('message', handleMessage, true);
145        </script>
146        <embed id="nacl_module"
147               src="my_application.nmf"
148               type="application/x-nacl" />
149      </div>
150
151 #. Implement a simple JavaScript handler that logs the messages it receives to
152    the JavaScript console:
153
154    .. naclcode::
155
156      function handleMessage(message_event) {
157        console.log(message_event.data);
158      }
159
160    This handler works in the simple case where the only messages your Native
161    Client module sends to JavaScript are messages with the output from stdout
162    and stderr. If your Native Client module also sends other messages to
163    JavaScript, your handler will need to be more complex.
164
165    Once you've implemented a message handler and set up the environment
166    variables as described above, you can check the JavaScript console to see
167    output that your Native Client module prints to stdout and stderr. Keep in
168    mind that your module makes a call to PostMessage() every time it flushes
169    stdout or stderr.  Your application's performance will degrade considerably
170    if your module prints and flushes frequently, or if it makes frequent Pepper
171    calls to begin with (e.g., to render).
172
173 Logging calls to Pepper interfaces
174 ----------------------------------
175
176 You can log all Pepper calls your module makes by passing the following flags
177 to Chrome on startup::
178
179   --vmodule=ppb*=4 --enable-logging=stderr
180
181
182 The ``vmodule`` flag tells Chrome to log all calls to C Pepper interfaces that
183 begin with "ppb" (that is, the interfaces that are implemented by the browser
184 and that your module calls). The ``enable-logging`` flag tells Chrome to log
185 the calls to stderr.
186
187 .. _visual_studio:
188
189 Debugging with Visual Studio
190 ----------------------------
191
192 If you develop on a Windows platform you can use the Native :doc:`Client Visual
193 Studio add-in <vs-addin>` to write and debug your code. The add-in defines new
194 project platforms that let you run your module in two different modes: As a
195 Pepper plugin and as a Native Client module. When running as a Pepper plugin
196 you can use the built-in Visual Studio debugger. When running as a Native
197 Client module Visual Studio will launch an instance of nacl-gdb for you and
198 link it to the running code.
199
200 .. _using_gdb:
201
202 Debugging with nacl-gdb
203 -----------------------
204
205 The Native Client SDK includes a command-line debugger that you can use to
206 debug Native Client modules. The debugger is based on the GNU debugger `gdb
207 <http://www.gnu.org/software/gdb/>`_, and is located at
208 ``toolchain/<platform>_<architecture>_<library>/bin/<prefix>-nacl-gdb``, where:
209
210 * *<platform>* is the platform of your development machine (win, mac, or linux)
211 * *<architecture>* is your target architecture (x86 or arm)
212 * *<library>* is the C library you are compiling with (newlib or glibc)
213 * *<prefix>* depends on the module you are debugging (i686- for x86 32-bit
214   modules, x86_64- for x86 64-bit modules, arm- for ARM modules)
215
216 For example, to debug an x86 64-bit module built with glibc on Windows, you
217 would use ``toolchain/win_x86_glibc/bin/x86_64-nacl-gdb``.
218
219 .. Note::
220   :class: note
221
222   **Prerequisites for using nacl-gdb**:
223
224   * You must use the pepper_23 bundle (or greater) in the SDK.
225   * Your version of Chrome must be greater than or equal to the Pepper bundle
226     that you are using. For example, if you are using the pepper_23 bundle, you
227     must use Chrome 23 or greater. Type about:chrome in the Chrome address bar
228     to find out what version of Chrome you have. You may want to install and
229     use Chrome Canary on Windows and Mac OS; it's the newest version of Chrome
230     that's available, and it runs side-by-side with your current version of
231     Chrome.
232
233 Before you start using nacl-gdb, make sure you can :doc:`build <building>` your
234 module and :doc:`run <running>` your application normally. This will verify
235 that you have created all the required :doc:`application parts
236 <../coding/application-structure>` (.html, .nmf, and .nexe files, shared
237 libraries, etc.), that your server can access those resources, and that you've
238 configured Chrome correctly to run your application.  The instructions below
239 assume that you are using a :ref:`local server <web_server>` to run your
240 application; one benefit of doing it this way is that you can check the web
241 server output to confirm that your application is loading the correct
242 resources. However, some people prefer to run their application as an unpacked
243 extension, as described in :doc:`Running Native Client Applications <running>`.
244
245 Follow the instructions below to debug your module with nacl-gdb:
246
247 #. Compile your module with the ``-g`` flag so that your .nexe retains symbols
248    and other debugging information (see the :ref:`recommended compile flags
249    <compile_flags>`).
250 #. Launch a local web server (e.g., the :ref:`web server <web_server>` included
251    in the SDK).
252 #. Launch Chrome with these three required flags: ``--enable-nacl --enable-nacl-debug --no-sandbox``.
253
254    You may also want to use some of the optional flags listed below. A typical
255    command looks like this::
256
257      chrome --enable-nacl --enable-nacl-debug --no-sandbox --disable-hang-monitor localhost:5103
258
259    **Required flags:**
260
261    ``--enable-nacl``
262      Enables Native Client for all applications, including those that are
263      launched outside the Chrome Web Store.
264
265    ``--enable-nacl-debug``
266      Turns on the Native Client debug stub, opens TCP port 4014, and pauses
267      Chrome to let the debugger connect.
268
269    ``--no-sandbox``
270      Turns off the Chrome sandbox (not the Native Client sandbox). This enables
271      the stdout and stderr streams, and lets the debugger connect.
272
273    **Optional flagsa:**
274
275    ``--disable-hang-monitor``
276      Prevents Chrome from displaying a warning when a tab is unresponsive.
277
278    ``--user-data-dir=<directory>``
279      Specifies the `user data directory
280      <http://www.chromium.org/user-experience/user-data-directory>`_ from which
281      Chrome should load its state.  You can specify a different user data
282      directory so that changes you make to Chrome in your debugging session do
283      not affect your personal Chrome data (history, cookies, bookmarks, themes,
284      and settings).
285
286    ``<URL>``
287      Specifies the URL Chrome should open when it launches. The local server
288      that comes with the SDK listens on port 5103 by default, so the URL when
289      you're debugging is typically ``localhost:5103`` (assuming that your
290      application's page is called index.html and that you run the local server
291      in the directory where that page is located).
292
293 #. Navigate to your application's page in Chrome. (You don't need to do this if
294    you specified a URL when you launched Chrome in the previous step.) Chrome
295    will start loading the application, then pause and wait until you start
296    nacl-gdb and run the ``continue`` command.
297
298 #. Go to the directory with your source code, and run nacl-gdb from there. For
299    example::
300
301      cd <NACL_SDK_ROOT>/examples/hello_world_gles
302      <NACL_SDK_ROOT>/toolchain/win_x86_newlib/bin/x86_64-nacl-gdb
303
304    The debugger will start and show you a gdb prompt::
305
306      (gdb)
307
308 #. Run the following three commands from the gdb command line::
309
310      (gdb) nacl-manifest <path-to-your-.nmf-file>
311      (gdb) nacl-irt <path-to-Chrome-NaCl-integrated-runtime>
312      (gdb) target remote localhost:4014
313
314    These commands are described below:
315
316    ``nacl-manifest <path>``
317      Tells the debugger about your Native Client application by pointing it to
318      the application's manifest (.nmf) file. The manifest file lists your
319      application's executable (.nexe) files, as well as any libraries that are
320      linked with the application dynamically.
321
322    ``nacl-irt <path>``
323      Tells the debugger where to find the Native Client Integrated Runtime
324      (IRT). The IRT is located in the same directory as the Chrome executable,
325      or in a subdirectory named after the Chrome version. For example, if
326      you're running Chrome canary on Windows, the path to the IRT typically
327      looks something like ``C:/Users/<username>/AppData/Local/Google/Chrome
328      SxS/Application/23.0.1247.1/nacl_irt_x86_64.nexe``.
329
330    ``target remote localhost:4014``
331      Tells the debugger how to connect to the debug stub in the Native Client
332      application loader. This connection occurs through TCP port 4014 (note
333      that this port is distinct from the port which the local web server uses
334      to listen for incoming requests, typically port 5103).
335
336    A couple of notes on how to specify path names in the nacl-gdb commands
337    above:
338
339    * You can use a forward slash to separate directories on Linux, Mac, and
340      Windows. If you use a backslash to separate directories on Windows, you
341      must escape the backslash by using a double backslash "\\" between
342      directories.
343    * If any directories in the path have spaces in their name, you must put
344      quotation marks around the path.
345
346    As an example, here is a what these nacl-gdb commands might look like on
347    Windows::
348
349      nacl-manifest "C:/<NACL_SDK_ROOT>/examples/hello_world_gles/newlib/Debug/hello_world_gles.nmf"
350      nacl-irt "C:/Users/<username>/AppData/Local/Google/Chrome SxS/Application/23.0.1247.1/nacl_irt_x86_64.nexe"
351      target remote localhost:4014
352
353    To save yourself some typing, you can put put these nacl-gdb commands in a
354    script file, and execute the file when you run nacl-gdb, like so::
355
356      <NACL_SDK_ROOT>/toolchain/win_x86_newlib/bin/x86_64-nacl-gdb -x <nacl-script-file>
357
358    If nacl-gdb connects successfully to Chrome, it displays a message such as
359    the one below, followed by a gdb prompt::
360
361      0x000000000fc00200 in _start ()
362      (gdb)
363
364    If nacl-gdb can't connect to Chrome, it displays a message such as
365    "``localhost:4014: A connection attempt failed``" or "``localhost:4014:
366    Connection timed out.``" If you see a message like that, make sure that you
367    have launched a web server, launched Chrome, and navigated to your
368    application's page before starting nacl-gdb.
369
370 Once nacl-gdb connects to Chrome, you can run standard gdb commands to execute
371 your module and inspect its state. Some commonly used commands are listed
372 below.
373
374 ``break <location>``
375   set a breakpoint at <location>, e.g.::
376
377     break hello_world.cc:79
378     break hello_world::HelloWorldInstance::HandleMessage
379     break Render
380
381 ``continue``
382   resume normal execution of the program
383
384 ``next``
385   execute the next source line, stepping over functions
386
387 ``step``
388   execute the next source line, stepping into functions
389
390 ``print <expression>``
391   print the value of <expression> (e.g., variables)
392
393 ``backtrace``
394   print a stack backtrace
395
396 ``info breakpoints``
397   print a table of all breakpoints
398
399 ``delete <breakpoint>``
400   delete the specified breakpoint (you can use the breakpoint number displayed
401   by the info command)
402
403 ``help <command>``
404   print documentation for the specified gdb <command>
405
406 ``quit``
407   quit gdb
408
409 See the `gdb documentation
410 <http://sourceware.org/gdb/current/onlinedocs/gdb/#toc_Top>`_ for a
411 comprehensive list of gdb commands. Note that you can abbreviate most commands
412 to just their first letter (``b`` for break, ``c`` for continue, and so on).
413
414 To interrupt execution of your module, press <Ctrl-c>. When you're done
415 debugging, close the Chrome window and type ``q`` to quit gdb.
416
417 Debugging with other tools
418 ==========================
419
420 If you cannot use the :ref:`Visual Studio add-in <visual_studio>`, or you want
421 to use a debugger other than nacl-gdb, you must manually build your module as a
422 Pepper plugin (sometimes referred to as a `"trusted
423 <http://www.chromium.org/nativeclient/getting-started/getting-started-background-and-basics#TOC-Trusted-vs-Untrusted>`_"
424 or "in-process" plugin).  Pepper plugins (.DLL files on Windows; .so files on
425 Linux; .bundle files on Mac) are loaded directly in either the Chrome renderer
426 process or a separate plugin process, rather than in Native Client. Building a
427 module as a trusted Pepper plugin allows you to use standard debuggers and
428 development tools on your system, but when you're finished developing the
429 plugin, you need to port it to Native Client (i.e., build the module with one
430 of the toolchains in the NaCl SDK so that the module runs in Native Client).
431 For details on this advanced development technique, see `Debugging a Trusted
432 Plugin
433 <http://www.chromium.org/nativeclient/how-tos/debugging-documentation/debugging-a-trusted-plugin>`_.
434 Note that starting with the ``pepper_22`` bundle, the NaCl SDK for Windows
435 includes pre-built libraries and library source code, making it much easier to
436 build a module into a .DLL.
437
438 Open source profiling tools
439 ---------------------------
440
441 For the brave-hearted there are open source tools at `Chromium.org
442 <http://www.chromium.org/nativeclient>`_ that describe how to do profiling on
443 `64-bit Windows
444 <https://sites.google.com/a/chromium.org/dev/nativeclient/how-tos/profiling-nacl-apps-on-64-bit-windows>`_
445 and `Linux
446 <http://www.chromium.org/nativeclient/how-tos/limited-profiling-with-oprofile-on-x86-64>`_
447 machines.
448
449
450 .. |menu-icon| image:: /images/menu-icon.png
451 .. |puzzle| image:: /images/puzzle.png