Index: native_client_sdk/src/doc/devguide/tutorial.rst |
diff --git a/native_client_sdk/src/doc/devguide/tutorial.rst b/native_client_sdk/src/doc/devguide/tutorial.rst |
index c636941b4b96e10a843ba619a5537fbd07f93d8d..13e605c5bd9f63eef69cd96586e574c9e8bd2c16 100644 |
--- a/native_client_sdk/src/doc/devguide/tutorial.rst |
+++ b/native_client_sdk/src/doc/devguide/tutorial.rst |
@@ -12,70 +12,40 @@ C++ Tutorial: Getting Started |
Overview |
======== |
-This tutorial shows you how to create, compile, and run a Native Client web |
-application. The Native Client module you will create as part of the web |
-application will be written in C++. |
+This tutorial shows how to build and run a web application using Portable Native |
+Client (PNaCl). This is a client-side application that uses HTML, JavaScript and |
+a Native Client module written in C++. The PNaCl toolchain is used to enable |
+running the Native Client module directly from a web page. |
-We recommend reading the :doc:`Native Client Technical Overview |
+It's recommended to read the :doc:`Native Client Technical Overview |
<../overview>` prior to going through this tutorial. |
-Parts in a Native Client application |
------------------------------------- |
- |
-A Native Client web application consists of at least three parts: |
-**TODO(binji)**: This is duplicated in the technical overview. Make sure it is |
-consistent in each. |
- |
-* A **web page** (*\*.html*) |
- |
- The web page can include HTML, JavaScript, and CSS (the JavaScript and CSS |
- can also go in separate .js and .css files). |
- |
-* A **Native Client module** (*\*.c* or *\*.cc* before compiling; *\*.nexe* |
- after compiling) |
- |
- Native Client modules can be written in C or C++. Modules use the Pepper API, |
- included in the SDK, as a bridge between the browser and the modules. |
- |
-* A **Manifest** file (*\*.nmf*) |
- |
- Browsers use an application's manifest file to determine which compiled Native |
- Client module to load based on the instruction set architecture of the user's |
- machine (e.g., x86-32, x86-64, or ARM). |
- |
What the application in this tutorial does |
------------------------------------------ |
The application in this tutorial shows how to load a Native Client module in a |
-web page, and how to send messages between JavaScript code and the C or C++ |
-code in the Native Client module. In this simple application, the JavaScript |
-code in the web page sends a 'hello' message to the Native Client module. When |
-the Native Client module receives a message, it checks whether the message is |
-equal to the string 'hello'. If it is, the Native Client module returns a |
-message saying 'hello from NaCl'. A JavaScript alert panel displays the message |
-received from the Native Client module. |
- |
-This tutorial also shows you how to create a set of template files that you can |
-use as a starting point for a Native Client application. The template code sets |
-up a simple message handler on the Native Client side, and includes boilerplate |
-code in the HTML file for adding an event listener to the web page to receive |
-messages from the Native Client module. |
- |
-Communication between JavaScript code and Native Client modules |
---------------------------------------------------------------- |
- |
-Communication between JavaScript code in the browser and C or C++ code in a |
-Native Client module is two-way: JavaScript code can send messages to the |
-Native Client module; the C or C++ code can respond to messages from |
-JavaScript, or it can initiate its own messages to JavaScript. In all cases, |
-the communication is asynchronous: The caller (the JavaScript code in the |
-browser or the C/C++ code in the Native Client module) sends a message, but the |
-caller does not wait for, or may not even expect, a response. This behavior is |
+web page, and how to send messages between JavaScript and the C++ code in the |
+Native Client module. In this simple application, the JavaScript code in the web |
+page sends a ``'hello'`` message to the Native Client module. When the Native |
+Client module receives a message, it checks whether the message is equal to the |
+string ``'hello'``. If it is, the Native Client module returns a message saying |
+``'hello from NaCl'``. A JavaScript alert panel displays the message received |
+from the Native Client module. |
+ |
+Communication between JavaScript and Native Client modules |
+---------------------------------------------------------- |
+ |
+The Native Client programming model supports bidirectional communication between |
+JavaScript and the Native Client module (C/C++ code). Both sides can initiate |
+and respond to messages. In all cases, the communication is asynchronous: The |
+caller (JavaScript or the Native Client module) sends a message, but the caller |
+does not wait for, or may not even expect, a response. This behavior is |
analogous to client/server communication on the web, where the client posts a |
message to the server and returns immediately. The Native Client messaging |
-system is part of the Pepper API, and is described in detail in the |
-:doc:`Messaging System <coding/message-system>` chapter in the Developer's |
-Guide. |
+system is part of the Pepper API, and is described in detail in |
+:doc:`Developer's Guide: Messaging System <coding/message-system>`. |
+ |
+TODO: would it be better to compare to web-worker communication? |
Step 1: Download and install the Native Client SDK |
================================================== |
@@ -83,311 +53,148 @@ Step 1: Download and install the Native Client SDK |
Follow the instructions on the :doc:`Download <../sdk/download>` page to |
download and install the Native Client SDK. |
-.. Note:: |
- :class: caution |
- |
- **Important:** A number of tools in the SDK require Python to run. Python is |
- typically included on Mac and Linux systems, but not on Windows systems. To |
- check whether you have Python installed on your system, enter the |
- '``python``' command on the command line; you should get the interactive |
- Python prompt (``>>>``). On Mac systems, you also need to install '``make``' |
- in order to build and run the examples in the SDK; one easy way to get |
- '``make``', along with several other useful tools, is to install Xcode |
- Developer Tools. Follow the instructions at the top of the :doc:`Download |
- <../sdk/download>` page if you need to install Python and/or Xcode |
- Developer Tools. |
+.. _tutorial_step_2: |
Step 2: Start a local server |
============================ |
-TODO(binji): This is not necessary anymore; we can use ``make run``. Some of |
-the information about why you need a webserver is still useful though... |
-Remove? |
- |
-To protect against security vulnerabilities, you must load Native Client |
-modules from a web server (either remote or local). **Simply dragging and |
-dropping Native Client files into the browser address bar will not work.** For |
-more information, read about the `Same Origin Policy |
-<http://www.w3.org/Security/wiki/Same_Origin_Policy>`_, which protects the |
-user's file system from outside access. |
- |
-The Native Client SDK includes a simple Python web server that you can use to |
-run applications that you build (including the application in this tutorial). |
-The server is located in the tools directory. To start the web server, go to |
-the examples directory in the SDK bundle that you are using and run the |
-``httpd.py`` script. For example, if you are using the ``pepper_28`` bundle, |
-run the following commands: |
+To simulate a production environment, the SDK provides a simple web server that |
+can be used to serve the application on ``localhost``. A convenience Makefile |
+rule called ``serve`` is the easiest way to invoke it: |
.. naclcode:: |
:prettyprint: 0 |
- cd pepper_28/examples |
- python ../tools/httpd.py |
+ $ cd pepper_$(VERSION)/getting_started |
+ $ make serve |
-If you don't specify a port number, the server defaults to port 5103, and you |
-can access the server at http://localhost:5103. |
+.. Note:: |
+ :class: note |
-Of course, you don't have to use the server included in the SDK---any web server |
-will do. If you prefer to use another web server already installed on your |
-system, that's fine. Note also that there are ways to run Native Client |
-applications during development without a server, but these techniques require |
-you to create additional files for your application (see :doc:`Running Native |
-Client Applications <devcycle/running>` for details). For this tutorial, |
-your application must come from a server. |
+ The SDK may consist of several "bundles", one per Chrome/Pepper version (see |
+ :doc:`versioning information <../version>`). In the sample invocation above |
+ ``pepper_$(VERSION)`` refers to the specific version you want to use. For |
+ example, ``pepper_31``. If you don't know which version you need, use the |
+ one labeled ``(stable)`` by ``naclsdk list``. See :doc:`Download the Native |
+ Client SDK <../sdk/download>` for more details. |
-.. _step_3: |
+If no port number is specified, the server defaults to port 5103, and can be |
+accessed at http://localhost:5103. |
-Step 3: Set up Google Chrome |
-============================ |
+Any server can be used for the purpose of development. The one provided with the |
+SDK is just a convenience, not a requirement. |
-Set up the Chrome browser as follows: |
+.. _tutorial_step_3: |
-a. Make sure you are using the minimum required version of Chrome. |
+Step 3: Set up the Chrome browser |
+================================= |
- * Your version of Chrome must be equal to or greater than the version of your |
- Pepper bundle. For example, if you're developing with the ``pepper_28`` |
- bundle, you must use Google Chrome version 28 or greater. To find out what |
- version of Chrome you're using, type ``about:chrome`` or ``about:version`` |
- in the Chrome address bar. |
+PNaCl is enabled by default in Chrome version 31 and later. Please make sure |
+that you have a suitable version to work through this tutorial. It's also |
+important to use a Chrome version that's the same or newer than the SDK bundle |
+used to build the Native Client modules. |
-b. Enable the Native Client flag in Chrome. (Native Client is enabled by |
- default for applications distributed through the Chrome Web Store. To run |
- Native Client applications that are not distributed through the Chrome Web |
- Store, e.g., applications that you build and run locally, you must |
- specifically enable the Native Client flag in Chrome.) |
+.. Note:: |
+ :class: note |
- * Type ``about:flags`` in the Chrome address bar and scroll down to "Native |
- Client". |
- * If the link below "Native Client" says "Disable", then Native Client is |
- already enabled and you don't need to do anything else. |
- * If the link below "Native Client" says "Enable", click the "Enable" link, |
- scroll down to the bottom of the page, and click the "Relaunch Now" button. |
- All browser windows will restart when you relaunch Chrome. |
+ To find out the version of Chrome, type ``about:chrome`` in the address bar. |
-c. Disable the Chrome cache. (Chrome caches resources aggressively; you should |
- disable the cache whenever you are developing a Native Client application in |
- order to make sure Chrome loads new versions of your application.) |
+For a better development experience, it's also recommended to disable the |
+Chrome cache. Chrome caches resources aggressively; disabling the cache helps |
+make sure that the latest version of the Native Client module is loaded during |
+development. |
- * Open Chrome's developer tools by clicking the menu icon |menu-icon| and |
- choosing Tools > Developer tools. |
- * Click the gear icon |gear-icon| in the bottom right corner of the Chrome |
- window. |
- * Under the "General" settings, check the box next to "Disable cache". |
+* Open Chrome's developer tools by clicking the menu icon |menu-icon| and |
+ choosing ``Tools > Developer tools``. |
+* Click the gear icon |gear-icon| in the bottom right corner of the Chrome |
+ window. |
+* Under the "General" settings, check the box next to "Disable cache (while |
+ DevTools is open)". |
+* Keep the Developer Tools pane open while developing Native Client |
+ applications. |
.. |menu-icon| image:: /images/menu-icon.png |
.. |gear-icon| image:: /images/gear-icon.png |
-Step 4: Create a set of stub files for your application |
-======================================================= |
+Step 4: Stub code for the tutorial |
+================================== |
-Create a set of stub files as follows: |
+The stub code for the tutorial is avalable in the SDK, in |
+``pepper_$(VERSION)/getting_started/part1``. It contains the following files: |
-a. Download `hello_tutorial.zip |
- <https://developers.google.com/native-client/devguide/hello_tutorial.zip>`_. |
+* ``index.html``: Contains the HTML layout of the page as well as the JavaScript |
+ code that interacts with the Native Client module. |
-b. Unzip hello_tutorial.zip: |
+ The Native Client module is included in the page with an ``<embed>`` tag that |
+ points to a manifest file. |
+* ``hello_tutorial.nmf``: A manifest file that's used to point the HTML to the |
+ Native Client module and optionally provide additional commands to the PNaCl |
+ translator that is part of the Chrome browser. |
+* ``hello_tutorial.cc``: C++ code for a simple Native Client module. |
+* ``Makefile``: Compilation commands to build the **pexe** (portable executable) |
+ from the C++ code in ``hello_tutorial.cc``. |
- * On Mac/Linux, run the command "``unzip hello_tutorial.zip``" in a Terminal |
- window. |
- * On Windows, right-click on the .zip file and select "Extract All..." A |
- dialog box will open; enter a location and click "Extract". |
+It's a good idea to take a look at these files now---they contain a large amount |
+of comments that help explain their structure and contents. For more details |
+on the structure of a typical Native Client application, see |
+:doc:`Application Structure <coding/application-structure>`. |
-c. Unzipping hello_tutorial.zip creates a directory called ``hello_tutorial`` |
- with the following files: |
+The stub code is intentionally very minimal. The C++ code does not do anything |
+except correctly initialize itself. The JavaScript code waits for the Native |
+Client module to load and changes the status text on the web page accordingly. |
- * ``hello_tutorial.html`` |
- * ``hello_tutorial.cc`` |
- * ``hello_tutorial.nmf`` |
- * ``Makefile`` |
- * ``make.bat`` (for Windows) |
+Step 5: Compile the Native Client module and run the stub application |
+===================================================================== |
-d. Move the ``hello_tutorial`` directory so that it's under the ``examples`` |
- directory where you started the local server. Its location should be, e.g., |
- ``pepper_28/examples/hello_tutorial``. |
+To compile the Native Client module, run ``make``: |
- * On Windows, depending on the location you entered when you unzipped the |
- file, there may be two ``hello_tutorial`` directories—one nested within |
- the other. Move only the inner (nested) directory to the ``examples`` |
- directory. |
+.. naclcode:: |
+ :prettyprint: 0 |
-.. Note:: |
- :class: note |
+ $ cd pepper_$(VERSION)/getting_started/part1 |
+ $ make |
- **Note regarding the location of project directories:** |
- |
- * In this tutorial, you are adding the ``hello_tutorial`` directory under the |
- ``examples`` directory because the ``examples`` directory is where your |
- local server is running, ready to serve your tutorial application. You can |
- place your project directory anywhere on your file system, as long as that |
- location is being served by your server. |
- * If you do place the ``hello_tutorial`` project directory in another |
- location, you must set the `environment variable |
- <http://en.wikipedia.org/wiki/Environment_variable>`_ ``NACL_SDK_ROOT`` to |
- point to the top-level directory of the bundle you are using (e.g., |
- ``<location-where-you-installed-the-SDK>/pepper_28``) in order for the |
- Makefile that's included in the project directory to work. |
- * If you use the location recommended above |
- (``pepper_28/examples/hello_tutorial``), be careful when you update the |
- SDK. The command '``naclsdk update pepper_28 --force``' will overwrite the |
- ``pepper_28`` directory, so move any project directories you want to keep |
- to another location. |
+Since the sample is located within the SDK tree, the Makefile knows how to find |
+the PNaCl toolchain automatically and use it to build the module. If you're |
+building applications outside the NaCl SDK tree, you should set the |
+``$NACL_SDK_ROOT`` environment variable. See :doc:`Building Native Client |
+Modules <devcycle/building>` for more details. |
-Step 5: Compile the Native Client module and run the stub application |
-===================================================================== |
+Assuming the local server was started according to the instructions in |
+:ref:`Step 2 <tutorial_step_2>`, you can now load the sample by pointing Chrome |
+to http://localhost:5103/part1. Chrome should load the Native Client module |
+successfully and the Status text should change from "LOADING..." to "SUCCESS". |
+If you run into problems, check out the :ref:`Troubleshooting section |
+<tutorial_troubleshooting>` below. |
-The files you downloaded in the previous step constitute a stub application |
-that simply loads a Native Client module into a web page and updates a |
-``<div>`` element on the page with the status of the module load. |
+Step 6: Modify the JavaScript code to send a message to the Native Client module |
+================================================================================ |
-To compile the Native Client module ``hello_tutorial.cc,`` run '``make``': |
+In this step, you'll modify the web page (``index.html``) to send a message to |
+the Native Client module after the page loads the module. |
-.. naclcode:: |
- :prettyprint: 0 |
- |
- cd pepper_28/examples/hello_tutorial |
- make |
- |
-The '``make``' command runs the necessary compile and link commands to produce |
-three executable Native Client modules (for the x86-32, x86-64, and ARM |
-architectures). The executable files are named as follows: |
- |
-* ``hello_tutorial_x86_32.nexe`` |
-* ``hello_tutorial_x86_64.nexe`` |
-* ``hello_tutorial_arm.nexe`` |
- |
-Assuming you are using the local server and the project directory specified |
-above, you can load the ``hello_tutorial.html`` web page into Chrome by visiting |
-the following URL: http://localhost:5103/hello_tutorial/hello_tutorial.html. If |
-Chrome loads the Native Client module successfully, the Status display on the |
-page should change from "LOADING..." to "SUCCESS". |
- |
-Step 6: Review the code in the stub application |
-=============================================== |
- |
-The section highlights some of the code in the stub application. |
- |
-Makefile |
- ``Makefile`` contains the compile and link commands to build the executable |
- Native Client modules (.nexe files) for your application. The Native Client |
- SDK includes multiple GCC‑based toolchains to build modules for multiple |
- architectures (x86 and ARM) using different implementations of the C library |
- (`newlib <http://www.sourceware.org/newlib/>`_ and `glibc |
- <http://www.gnu.org/software/libc/>`_). The commands in the tutorial |
- ``Makefile`` build the application using the newlib C library for the x86 and |
- ARM architectures. The commands use the toolchains located in the |
- ``pepper_28/toolchain/<platform>_x86_newlib`` and ``<platform>_arm_newlib`` |
- directories. For information about how to use Makefiles and the '``make``' |
- command, see the `GNU 'make' manual |
- <http://www.gnu.org/software/make/manual/make.html>`_. |
- |
-hello_tutorial.nmf |
- ``hello_tutorial.nmf`` is a Native Client manifest file that tells Chrome |
- which compiled Native Client module (.nexe) to load based on the instruction |
- set architecture of the user's machine (e.g., x86-32, x86-64, or ARM). For |
- applications compiled using glibc, manifest files must also specify the |
- shared libraries that the applications use. |
- |
-hello_tutorial.html |
- ``hello_tutorial.html`` is the web page that corresponds to your application. |
- The page includes an ``<embed>`` element that loads the compiled Native |
- Client module: |
- |
- .. naclcode:: |
- |
- <div id="listener"> |
- <script type="text/javascript"> |
- var listener = document.getElementById('listener'); |
- listener.addEventListener('load', moduleDidLoad, true); |
- listener.addEventListener('message', handleMessage, true); |
- </script> |
- |
- <embed name="nacl_module" |
- id="hello_tutorial" |
- width=0 height=0 |
- src="hello_tutorial.nmf" |
- type="application/x-nacl" /> |
- </div> |
- |
- The ``src`` attribute in the ``<embed>`` element points to the Native Client |
- manifest file, which tells the browser which .nexe file to load based on the |
- instruction set architecture of the user's machine. The ``width`` and |
- ``height`` attributes in the ``<embed>`` element are set to 0 because the |
- Native Client module in this example does not have any graphical component. |
- The ``type`` attribute declares the MIME type to be ``x-nacl``, i.e., an |
- executable Native Client module. |
- |
- The ``<embed>`` element is wrapped inside a ``<div>`` element that has two |
- event listeners attached—one for the 'load' event, which fires when the |
- browser successfully loads the Native Client module, and one for the |
- 'message' event, which fires when the Native Client module uses the |
- ``PostMessage()`` method (in the `pp::Instance |
- <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance>`_ |
- class) to send a message to the JavaScript code in the application. This |
- technique of attaching the event listeners to a parent ``<div>`` element |
- (rather than directly to the ``<embed>`` element) is used to ensure that the |
- event listeners are active before the module 'load' event fires. |
- |
- The simple event handlers in this tutorial are implemented in the |
- ``moduleDidLoad()`` and ``handleMessage()`` JavaScript functions. |
- ``moduleDidLoad()`` changes the text inside the 'status_field' ``<div>`` |
- element. handleMessage() displays the content of messages sent from the |
- Native Client module in a browser alert panel. For a description of 'load', |
- 'message', and other Native Client events, see the :doc:`Progress Events |
- <coding/progress-events>` chapter of the Developer's Guide. |
- |
-hello_tutorial.cc |
- Native Client includes the concept of modules and instances: |
- |
- * A **module** is C or C++ code compiled into an executable .nexe file. |
- * An **instance** is a rectangle on a web page that is managed by a module. |
- The rectangle can have dimensions 0x0, in which case the instance does not |
- have a visual component on the web page. An instance is created by |
- including an ``<embed>`` element in a web page. A module may be included in |
- a web page multiple times by using multiple ``<embed>`` elements that refer |
- to the module; in this case the Native Client runtime system loads the |
- module once and creates multiple instances that are managed by the module. |
- |
- The example in this tutorial includes one module |
- (``hello_tutorial_x86_32.nexe``, ``hello_tutorial_x86_64.nexe``, or |
- ``hello_tutorial_arm.nexe``, depending on the instruction set architecture of |
- the user's machine), and one instance (one ``<embed>`` element that loads the |
- module). The source code for the module is in the file ``hello_tutorial.cc``. |
- This source code contains the minimum code required in a C++ Native Client |
- module—an implementation of the `Instance |
- <https://developers.google.com/native-client/peppercpp/classpp_1_1_instance>`_ |
- and `Module |
- <https://developers.google.com/native-client/peppercpp/classpp_1_1_module>`_ |
- classes. These implementations don't actually do anything yet. |
- |
-Step 7: Modify the web page to send a message to the Native Client module |
-========================================================================= |
- |
-In this step, you'll modify the web page (``hello_tutorial.html``) to send a |
-message to the Native Client module after the page loads the module. |
- |
-Look for the JavaScript function ``moduleDidLoad()``, and add the new code below |
-(indicated by boldface type) to send a 'hello' message to the Native Client |
-module: |
+Look for the JavaScript function ``moduleDidLoad()``, and add new code to send |
+a 'hello' message to the module. The new function should look as follows: |
.. naclcode:: |
- function moduleDidLoad() { |
- HelloTutorialModule = document.getElementById('hello_tutorial'); |
- updateStatus('SUCCESS'); |
- // Send a message to the NaCl module. |
- HelloTutorialModule.postMessage('hello'); |
- } |
+ function moduleDidLoad() { |
+ HelloTutorialModule = document.getElementById('hello_tutorial'); |
+ updateStatus('SUCCESS'); |
+ // Send a message to the Native Client module |
+ HelloTutorialModule.postMessage('hello'); |
+ } |
-Step 8: Implement a message handler in the Native Client module |
+Step 7: Implement a message handler in the Native Client module |
=============================================================== |
In this step, you'll modify the Native Client module (``hello_tutorial.cc``) to |
respond to the message received from the JavaScript code in the application. |
Specifically, you'll: |
-* implement the ``HandleMessage()`` function for the module, and |
-* use the ``PostMessage()`` function to send a message from the module to the |
- JavaScript code |
+* Implement the ``HandleMessage()`` member function of the module instance. |
+* Use the ``PostMessage()`` member function to send a message from the module to |
+ the JavaScript code. |
First, add code to define the variables used by the Native Client module (the |
'hello' string you're expecting to receive from JavaScript and the reply string |
@@ -404,14 +211,14 @@ you want to return to JavaScript as a response). In the file |
const char* const kReplyString = "hello from NaCl"; |
} // namespace |
-Now, implement the ``HandleMessage()`` method to check for ``kHelloString`` and |
-return ``kReplyString.`` Look for the following line: |
+Now, implement the ``HandleMessage()`` member function to check for |
+``kHelloString`` and return ``kReplyString.`` Look for the following line: |
.. naclcode:: |
// TODO(sdk_user): 1. Make this function handle the incoming message. |
-Replace the above line with the boldface code below: |
+Populate the member function with code, as follows: |
.. naclcode:: |
@@ -431,33 +238,42 @@ See the Pepper API documentation for additional information about the |
<https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html#a5dce8c8b36b1df7cfcc12e42397a35e8>`_ |
and `pp::Instance.PostMessage |
<https://developers.google.com/native-client/peppercpp/classpp_1_1_instance.html#a67e888a4e4e23effe7a09625e73ecae9>`_ |
-methods. |
+member functions. |
-Step 9: Compile the Native Client module and run the application again |
+Step 8: Compile the Native Client module and run the application again |
====================================================================== |
-Compile the Native Client module by running the '``make``' command again. |
+Compile the Native Client module by running the ``make`` command again. |
-Run the application by reloading hello_tutorial.html in Chrome. (The page |
-should be at http://localhost:5103/hello_tutorial/hello_tutorial.html assuming |
-the setup described above.) |
+Re-run the application by reloading http://localhost:5103/part1 in Chrome. |
After Chrome loads the Native Client module, you should see an alert panel |
appear with the message sent from the module. |
+.. _tutorial_troubleshooting: |
+ |
Troubleshooting |
=============== |
-If your application doesn't run, see :ref:`Step 3 <step_3>` above |
-to verify that you've set up your environment correctly, including both the |
-Chrome browser and the local server. Make sure that you're running a version of |
-Chrome that is equal to or greater than the SDK bundle version you are using, |
-that you've enabled the Native Client flag and relaunched Chrome, that you've |
-disabled the Chrome cache, and that **you're accessing your application from a |
-local web server (rather than by dragging the HTML file into your browser)**. |
+If your application doesn't run, see :ref:`Step 3 <tutorial_step_3>` above to |
+verify that you've set up your environment correctly, including both the Chrome |
+browser and the local server. Make sure that you're running a correct version of |
+Chrome, which is also greater or equal than the SDK bundle version you are |
+using. |
+ |
+Another useful debugging aid is the Chrome JavaScript console (available via the |
+``Tools`` menu in Chrome). Examine it for clues about what went wrong. For |
+example, if there's a message saying "NaCl module crashed", there is a |
+possibility that the Native Client module has a bug; :doc:`debugging |
+<devcycle/debugging>` may be required. |
+ |
+There's more information about troubleshooting in the documentation: |
+ |
+* `FAQ <https://developers.google.com/native-client/faq.html#HangOnLoad>`_. |
+* The :doc:`Progress Events <coding/progress-events>` document contains some |
+ useful information about handling error events. |
-For additional troubleshooting information, check the `FAQ |
-<https://developers.google.com/native-client/faq.html#HangOnLoad>`_. |
+.. TODO: fix FAQ link and others to :ref:/:doc: once ReST-ified. |
Next steps |
========== |