]> granicus.if.org Git - esp-idf/commitdiff
examples: add C++ exception handling example
authorIvan Grokhotkov <ivan@espressif.com>
Tue, 4 Sep 2018 02:20:29 +0000 (10:20 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Tue, 4 Sep 2018 13:00:14 +0000 (21:00 +0800)
docs/en/api-guides/error-handling.rst
examples/system/cpp_exceptions/Makefile [new file with mode: 0644]
examples/system/cpp_exceptions/README.md [new file with mode: 0644]
examples/system/cpp_exceptions/example_test.py [new file with mode: 0644]
examples/system/cpp_exceptions/main/component.mk [new file with mode: 0644]
examples/system/cpp_exceptions/main/exception_example_main.cpp [new file with mode: 0644]
examples/system/cpp_exceptions/sdkconfig.defaults [new file with mode: 0644]

index 284bcc753f4874bd30680fcf8d2181ebc34b7a56..b3e88a06f83a2d298765fff55427eb2e56271c48 100644 (file)
@@ -119,4 +119,5 @@ Enabling exception handling normally increases application binary size by a few
 
 If an exception is thrown, but there is no ``catch`` block, the program will be terminated by ``abort`` function, and backtrace will be printed. See :doc:`Fatal Errors <fatal-errors>` for more information about backtraces.
 
+See :example:`system/cpp_exceptions` for an example of C++ exception handling.
 
diff --git a/examples/system/cpp_exceptions/Makefile b/examples/system/cpp_exceptions/Makefile
new file mode 100644 (file)
index 0000000..bbca3f7
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# This is a project Makefile. It is assumed the directory this Makefile resides in is a
+# project subdirectory.
+#
+
+PROJECT_NAME := cpp_exceptions_example
+
+include $(IDF_PATH)/make/project.mk
+
diff --git a/examples/system/cpp_exceptions/README.md b/examples/system/cpp_exceptions/README.md
new file mode 100644 (file)
index 0000000..0ff49f3
--- /dev/null
@@ -0,0 +1,41 @@
+# Example: C++ exception handling
+
+(See the README.md file in the upper level 'examples' directory for more information about examples.)
+
+This example demonstrates usage of C++ exceptions in ESP-IDF.
+
+By default, C++ exceptions support is disabled in ESP-IDF. It can be enabled using `CONFIG_CXX_EXCEPTIONS` configuration option.
+
+In this example, `sdkconfig.defaults` file sets `CONFIG_CXX_EXCEPTIONS` option. This enables both compile time support (`-fexceptions` compiler flag) and run-time support for C++ exception handling.
+
+Example source code declares a class which can throw exception from the constructor, depending on the argument. It illustrates that exceptions can be thrown and caught using standard C++ facilities.
+
+## How to use example
+
+### Configure the project
+
+Run `make menuconfig` and set serial port under Serial Flasher Options.
+
+### Build and Flash
+
+Build the project and flash it to the board, then run monitor tool to view serial output:
+
+```
+make -j4 flash monitor
+```
+
+(To exit the serial monitor, type ``Ctrl-]``.)
+
+See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
+
+## Example Output
+
+```
+app_main starting
+In constructor, arg=42
+In constructor, arg=0
+In destructor, m_arg=42
+Exception caught: Exception in constructor
+app_main done
+```
+
diff --git a/examples/system/cpp_exceptions/example_test.py b/examples/system/cpp_exceptions/example_test.py
new file mode 100644 (file)
index 0000000..29a1324
--- /dev/null
@@ -0,0 +1,28 @@
+from __future__ import print_function
+import os
+import sys
+
+test_fw_path = os.getenv('TEST_FW_PATH')
+if test_fw_path and test_fw_path not in sys.path:
+    sys.path.insert(0, test_fw_path)
+
+import TinyFW
+import IDF
+
+@IDF.idf_example_test(env_tag='Example_WIFI')
+def test_examples_system_cpp_exceptions(env, extra_data):
+    dut = env.get_dut('cpp_exceptions_example', 'examples/system/cpp_exceptions')
+    # start test
+    dut.start_app()
+    lines = ['app_main starting',
+             'In constructor, arg=42',
+             'In constructor, arg=0',
+             'In destructor, m_arg=42',
+             'Exception caught: Exception in constructor',
+             'app_main done'
+    ]
+    for line in lines:
+        dut.expect(line, timeout=2)
+
+if __name__ == '__main__':
+    test_examples_system_cpp_exceptions()
diff --git a/examples/system/cpp_exceptions/main/component.mk b/examples/system/cpp_exceptions/main/component.mk
new file mode 100644 (file)
index 0000000..a98f634
--- /dev/null
@@ -0,0 +1,4 @@
+#
+# "main" pseudo-component makefile.
+#
+# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
diff --git a/examples/system/cpp_exceptions/main/exception_example_main.cpp b/examples/system/cpp_exceptions/main/exception_example_main.cpp
new file mode 100644 (file)
index 0000000..24ada9d
--- /dev/null
@@ -0,0 +1,56 @@
+/* C++ exception handling example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include <iostream>
+
+using std::cout;
+using std::endl;
+using std::runtime_error;
+
+/* A simple class which may throw an exception from constructor */
+class Throwing
+{
+public:
+    Throwing(int arg)
+    : m_arg(arg)
+    {
+        cout << "In constructor, arg=" << arg << endl;
+        if (arg == 0) {
+            throw runtime_error("Exception in constructor");
+        }
+    }
+
+    ~Throwing()
+    {
+        cout << "In destructor, m_arg=" << m_arg << endl;
+    }
+
+protected:
+    int m_arg;
+};
+
+/* Inside .cpp file, app_main function must be declared with C linkage */
+extern "C" void app_main()
+{
+    cout << "app_main starting" << endl;
+
+    try {
+        /* This will succeed */
+        Throwing obj1(42);
+
+        /* This will throw an exception */
+        Throwing obj2(0);
+
+        cout << "This will not be printed" << endl;
+    } catch (const runtime_error &e) {
+        cout << "Exception caught: " << e.what() << endl;
+    }
+
+    cout << "app_main done" << endl;
+}
diff --git a/examples/system/cpp_exceptions/sdkconfig.defaults b/examples/system/cpp_exceptions/sdkconfig.defaults
new file mode 100644 (file)
index 0000000..e9d7fca
--- /dev/null
@@ -0,0 +1,3 @@
+# Enable C++ exceptions and set emergency pool size for exception objects
+CONFIG_CXX_EXCEPTIONS=y
+CONFIG_CXX_EXCEPTIONS_EMG_POOL_SIZE=1024