From 1ec24234e36cb066c9a94f1547a1e1f9ff5db3a6 Mon Sep 17 00:00:00 2001 From: wusongqing Date: Wed, 25 May 2022 14:07:31 +0800 Subject: [PATCH] updated readme and website Signed-off-by: wusongqing --- en/application-dev/Readme-EN.md | 8 +- en/application-dev/media/Readme-EN.md | 4 +- en/application-dev/napi/Readme-EN.md | 3 + en/application-dev/reference/Readme-EN.md | 16 +- .../native-lib/third_party_libuv/libuv.md | 18 ++ .../native-lib/third_party_napi/napi.md | 130 +++++++++ en/contribute/code-contribution.md | 1 - en/device-dev/Readme-EN.md | 9 +- en/device-dev/porting/Readme-EN.md | 1 - .../porting-smallchip-driver-overview.md | 2 +- en/device-dev/quick-start/Readme-EN.md | 2 +- ...> quickstart-lite-steps-hi3861-running.md} | 0 .../quickstart-lite-steps-hi3861.md | 3 +- en/device-dev/subsystems/Readme-EN.md | 5 +- .../figure/process_crash_handling.png | Bin 0 -> 56322 bytes .../subsystems/subsys-dfx-faultlogger.md | 268 ++++++++++++++++++ .../subsystems/subsys-testguide-test.md | 2 +- en/device-dev/subsystems/subsys-xts-guide.md | 5 +- en/device-dev/subsystems/subsys.md | 4 +- en/device-dev/website.md | 39 +-- en/website.md | 7 +- zh-cn/device-dev/quick-start/Readme-CN.md | 4 +- ...> quickstart-lite-steps-hi3861-running.md} | 0 .../quickstart-lite-steps-hi3861.md | 2 +- zh-cn/device-dev/website.md | 4 +- 25 files changed, 484 insertions(+), 53 deletions(-) create mode 100644 en/application-dev/napi/Readme-EN.md create mode 100644 en/application-dev/reference/native-lib/third_party_libuv/libuv.md create mode 100644 en/application-dev/reference/native-lib/third_party_napi/napi.md rename en/device-dev/quick-start/{quickstart-lite-steps-hi3816-running.md => quickstart-lite-steps-hi3861-running.md} (100%) create mode 100644 en/device-dev/subsystems/figure/process_crash_handling.png create mode 100644 en/device-dev/subsystems/subsys-dfx-faultlogger.md rename zh-cn/device-dev/quick-start/{quickstart-lite-steps-hi3816-running.md => quickstart-lite-steps-hi3861-running.md} (100%) diff --git a/en/application-dev/Readme-EN.md b/en/application-dev/Readme-EN.md index 4c9056682a..6be76dd106 100644 --- a/en/application-dev/Readme-EN.md +++ b/en/application-dev/Readme-EN.md @@ -35,6 +35,7 @@ - [Device Usage Statistics](device-usage-statistics/Readme-EN.md) - [DFX](dfx/Readme-EN.md) - [Internationalization](internationalization/Readme-EN.md) + - [Native APIs](napi/Readme-EN.md) - Tools - [DevEco Studio (OpenHarmony) User Guide](quick-start/deveco-studio-user-guide-for-openharmony.md) - Hands-On Tutorials @@ -43,6 +44,11 @@ - API References - [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md) - [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md) - - [APIs](reference/apis/Readme-EN.md) + - APIs + - [JS (eTS Incldued) APIs](reference/apis/Readme-EN.md) + - Native APIs + - [Standard Library](reference/native-lib/third_party_libc/musl.md) + - [Node_API](reference/native-lib/third_party_napi/napi.md) - Contribution - [How to Contribute](../contribute/documentation-contribution.md) + diff --git a/en/application-dev/media/Readme-EN.md b/en/application-dev/media/Readme-EN.md index e1997f5069..b47160b577 100755 --- a/en/application-dev/media/Readme-EN.md +++ b/en/application-dev/media/Readme-EN.md @@ -4,11 +4,9 @@ - [Audio Overview](audio-overview.md) - [Audio Playback Development](audio-playback.md) - - [Audio Recording Development](audio-recorder.md) - [Audio Rendering Development](audio-renderer.md) - - - [Audio Capture Development](audio-capturer) + - [Audio Capture Development](audio-capturer.md) - Video - [Video Playback Development](video-playback.md) diff --git a/en/application-dev/napi/Readme-EN.md b/en/application-dev/napi/Readme-EN.md new file mode 100644 index 0000000000..33670e46af --- /dev/null +++ b/en/application-dev/napi/Readme-EN.md @@ -0,0 +1,3 @@ +# Native APIs + +- [Using Native APIs in Application Projects](napi-guidelines.md) diff --git a/en/application-dev/reference/Readme-EN.md b/en/application-dev/reference/Readme-EN.md index 0730fd77fd..7100b4253c 100644 --- a/en/application-dev/reference/Readme-EN.md +++ b/en/application-dev/reference/Readme-EN.md @@ -1,7 +1,15 @@ # Development References -- [JavaScript-based Web-like Development Paradigm](arkui-js/Readme-EN.md) -- [TypeScript-based Declarative Development Paradigm](arkui-ts/Readme-EN.md) -- [APIs](apis/Readme-EN.md) +- [JavaScript-based Web-like Development Paradigm](arkui-js/Readme-EN.md) + +- [TypeScript-based Declarative Development Paradigm](arkui-ts/Readme-EN.md) + +- APIs + + - [JS (eTS Included) APIs](apis/Readme-EN.md) + - Native APIs + - [Standard Library](native-lib/third_party_libc/musl.md) + - [Node_API](native-lib/third_party_napi/napi.md) - \ No newline at end of file + + diff --git a/en/application-dev/reference/native-lib/third_party_libuv/libuv.md b/en/application-dev/reference/native-lib/third_party_libuv/libuv.md new file mode 100644 index 0000000000..5fbe606083 --- /dev/null +++ b/en/application-dev/reference/native-lib/third_party_libuv/libuv.md @@ -0,0 +1,18 @@ +# libuv + + + +## Introduction + + + +libuv is a cross-platform library that implements asynchronous I/O based on event loops. It is mainly used in Node.js. + +## Supported Capabilities + + + +libuv implements cross-platform asynchronous I/O based on event loops. + +It supports standard lib interfaces. + diff --git a/en/application-dev/reference/native-lib/third_party_napi/napi.md b/en/application-dev/reference/native-lib/third_party_napi/napi.md new file mode 100644 index 0000000000..c3167109f2 --- /dev/null +++ b/en/application-dev/reference/native-lib/third_party_napi/napi.md @@ -0,0 +1,130 @@ +# Node_API + + + +## Introduction + + + +Node-API is an API used to encapsulate JavaScript capabilities as native plug-ins. It is independent of the underlying JavaScript and is maintained as part of Node.js. + +## Supported Capabilities + + + +Node-API eliminates the differences between underlying JavaScript engines and provides a set of stable interfaces. + +The NAPI component re-implements the Node-API and connects to underlying engines such as ArkJs. Currently, some interfaces in the Node-API standard library are supported. + +**List of Extended Symbols of NAPI** + +|Type|Symbol|Description| +| --- | --- | --- | +|FUNC|napi_run_script_path|Runs a JavaScript file.| + +**List of Symbols Exported from the Standard Library** + +|Type|Symbol|Description| +| --- | --- | --- | +|FUNC|napi_module_register| +|FUNC|napi_get_last_error_info| +|FUNC|napi_throw| +|FUNC|napi_throw_error| +|FUNC|napi_throw_type_error| +|FUNC|napi_throw_range_error| +|FUNC|napi_is_error| +|FUNC|napi_create_error| +|FUNC|napi_create_type_error| +|FUNC|napi_create_range_error| +|FUNC|napi_get_and_clear_last_exception| +|FUNC|napi_is_exception_pending| +|FUNC|napi_fatal_error| +|FUNC|napi_open_handle_scope| +|FUNC|napi_close_handle_scope| +|FUNC|napi_open_escapable_handle_scope| +|FUNC|napi_close_escapable_handle_scope| +|FUNC|napi_escape_handle| +|FUNC|napi_create_reference| +|FUNC|napi_delete_reference| +|FUNC|napi_reference_ref| +|FUNC|napi_reference_unref| +|FUNC|napi_get_reference_value| +|FUNC|napi_create_array| +|FUNC|napi_create_array_with_length| +|FUNC|napi_create_arraybuffer| +|FUNC|napi_create_external| +|FUNC|napi_create_external_arraybuffer| +|FUNC|napi_create_object| +|FUNC|napi_create_symbol| +|FUNC|napi_create_typedarray| +|FUNC|napi_create_dataview| +|FUNC|napi_create_int32| +|FUNC|napi_create_uint32| +|FUNC|napi_create_int64| +|FUNC|napi_create_double| +|FUNC|napi_create_string_latin1| +|FUNC|napi_create_string_utf8| +|FUNC|napi_get_array_length| +|FUNC|napi_get_arraybuffer_info| +|FUNC|napi_get_prototype| +|FUNC|napi_get_typedarray_info| +|FUNC|napi_get_dataview_info| +|FUNC|napi_get_value_bool| +|FUNC|napi_get_value_double| +|FUNC|napi_get_value_external| +|FUNC|napi_get_value_int32| +|FUNC|napi_get_value_int64| +|FUNC|napi_get_value_string_latin1| +|FUNC|napi_get_value_string_utf8| +|FUNC|napi_get_value_uint32| +|FUNC|napi_get_boolean| +|FUNC|napi_get_global| +|FUNC|napi_get_null| +|FUNC|napi_get_undefined| +|FUNC|napi_coerce_to_bool| +|FUNC|napi_coerce_to_number| +|FUNC|napi_coerce_to_object| +|FUNC|napi_coerce_to_string| +|FUNC|napi_typeof| +|FUNC|napi_instanceof| +|FUNC|napi_is_array| +|FUNC|napi_is_arraybuffer| +|FUNC|napi_is_typedarray| +|FUNC|napi_is_dataview| +|FUNC|napi_is_date| +|FUNC|napi_strict_equals| +|FUNC|napi_get_property_names| +|FUNC|napi_set_property| +|FUNC|napi_get_property| +|FUNC|napi_has_property| +|FUNC|napi_delete_property| +|FUNC|napi_has_own_property| +|FUNC|napi_set_named_property| +|FUNC|napi_get_named_property| +|FUNC|napi_has_named_property| +|FUNC|napi_set_element| +|FUNC|napi_get_element| +|FUNC|napi_has_element| +|FUNC|napi_delete_element| +|FUNC|napi_define_properties| +|FUNC|napi_call_function| +|FUNC|napi_create_function| +|FUNC|napi_get_cb_info| +|FUNC|napi_get_new_target| +|FUNC|napi_new_instance| +|FUNC|napi_define_class| +|FUNC|napi_wrap| +|FUNC|napi_unwrap| +|FUNC|napi_remove_wrap| +|FUNC|napi_create_async_work| +|FUNC|napi_delete_async_work| +|FUNC|napi_queue_async_work| +|FUNC|napi_cancel_async_work| +|FUNC|napi_get_node_version| +|FUNC|napi_get_version| +|FUNC|napi_create_promise| +|FUNC|napi_resolve_deferred| +|FUNC|napi_reject_deferred| +|FUNC|napi_is_promise| +|FUNC|napi_run_script| +|FUNC|napi_get_uv_event_loop| diff --git a/en/contribute/code-contribution.md b/en/contribute/code-contribution.md index 745343f109..4c340a50ad 100644 --- a/en/contribute/code-contribution.md +++ b/en/contribute/code-contribution.md @@ -29,7 +29,6 @@ For details, see [Contribution Process](contribution-process.md). ## Security Issue Disclosure - [Security Issue Handling and Release Processes](https://gitee.com/openharmony/security/blob/master/en/security-process/README.md) - - [OpenHarmony Security Vulnerability Notice](https://gitee.com/openharmony/security/blob/master/en/security-process/security-disclosure.md) diff --git a/en/device-dev/Readme-EN.md b/en/device-dev/Readme-EN.md index ff023f452e..b400c789ec 100644 --- a/en/device-dev/Readme-EN.md +++ b/en/device-dev/Readme-EN.md @@ -32,8 +32,8 @@ - [Sensor](subsystems/subsys-sensor.md) - [USB](subsystems/subsys-usbservice.md) - [Application Framework](subsystems/subsys-application-framework.md) - - [OTA Upgrade](subsystems/subsys-ota-guide.md) - - [Telephony Service](subsystems/subsys-tel.md) + - [OTA Update](subsystems/subsys-ota-guide.md) + - [Telephony](subsystems/subsys-tel.md) - [Security](subsystems/subsys-security.md) - [Startup](subsystems/subsys-boot.md) - [DFX](subsystems/subsys-dfx.md) @@ -43,16 +43,15 @@ - [Mini- and Small-System Devices](guide/device-lite.md) - [Standard-System Devices](guide/device-standard.md) - Debugging - - [Test](subsystems/subsys-testguide-test.md) + - [Test Case Development](subsystems/subsys-testguide-test.md) - [R&D Tools](subsystems/subsys-toolchain.md) - XTS Certification - - [XTS](subsystems/subsys-xts-guide.md) + - [XTS Test Case Development](subsystems/subsys-xts-guide.md) - Tools - [Docker Environment](get-code/gettools-acquire.md) - [IDE](get-code/gettools-ide.md) - Hands-On Tutorials - - [Samples](https://gitee.com/openharmony/app_samples/blob/master/README.md) - [Codelabs](https://gitee.com/openharmony/codelabs) - References - [FAQs](faqs/Readme-EN.md) diff --git a/en/device-dev/porting/Readme-EN.md b/en/device-dev/porting/Readme-EN.md index 238773053c..14788b0cf1 100644 --- a/en/device-dev/porting/Readme-EN.md +++ b/en/device-dev/porting/Readme-EN.md @@ -62,5 +62,4 @@ The download steps for other resources are the same as those in the mainline ver - [Mini System SoC Porting Cases](porting-minichip-cases.md) - [Mini-System Devices with Screens — Bestechnic SoC Porting Case](porting-bes2600w-on-minisystem-display-demo.md) - - [Combo Solution – ASR Chip Porting Case](porting-asr582x-combo-demo.md) diff --git a/en/device-dev/porting/porting-smallchip-driver-overview.md b/en/device-dev/porting/porting-smallchip-driver-overview.md index 117cd129bf..9147e903f6 100644 --- a/en/device-dev/porting/porting-smallchip-driver-overview.md +++ b/en/device-dev/porting/porting-smallchip-driver-overview.md @@ -1,4 +1,4 @@ -# Overview +# Porting Overview Drivers can be classified as platform drivers or device drivers. The platform drivers are generally in the SoC, such as the GPIO, I2C, and SPI drivers. The device drivers are typically outside of the SoC, such as the LCD, TP, and WLAN drivers. diff --git a/en/device-dev/quick-start/Readme-EN.md b/en/device-dev/quick-start/Readme-EN.md index b49cc02532..c7450bd439 100644 --- a/en/device-dev/quick-start/Readme-EN.md +++ b/en/device-dev/quick-start/Readme-EN.md @@ -32,7 +32,7 @@ - [Burning](quickstart-lite-steps-hi3861-burn.md) - [Networking](quickstart-lite-steps-hi3861-netconfig.md) - [Debugging and Verification](quickstart-lite-steps-hi3861-debug.md) - - [Running](quickstart-lite-steps-hi3816-running.md) + - [Running](quickstart-lite-steps-hi3861-running.md) - Hi3516 Development Board - [Setting Up the Hi3516 Development Board Environment](quickstart-lite-steps-hi3516-setting.md) - [Writing a Hello World Program](quickstart-lite-steps-hi3516-application-framework.md) diff --git a/en/device-dev/quick-start/quickstart-lite-steps-hi3816-running.md b/en/device-dev/quick-start/quickstart-lite-steps-hi3861-running.md similarity index 100% rename from en/device-dev/quick-start/quickstart-lite-steps-hi3816-running.md rename to en/device-dev/quick-start/quickstart-lite-steps-hi3861-running.md diff --git a/en/device-dev/quick-start/quickstart-lite-steps-hi3861.md b/en/device-dev/quick-start/quickstart-lite-steps-hi3861.md index d91f35a59f..0f637821f5 100644 --- a/en/device-dev/quick-start/quickstart-lite-steps-hi3861.md +++ b/en/device-dev/quick-start/quickstart-lite-steps-hi3861.md @@ -14,4 +14,5 @@ - **[Debugging and Verification](quickstart-lite-steps-hi3861-debug.md)** -- **[Running](quickstart-lite-steps-hi3816-running.md)** +- **[Running](quickstart-lite-steps-hi3861-running.md)** + diff --git a/en/device-dev/subsystems/Readme-EN.md b/en/device-dev/subsystems/Readme-EN.md index dab9c6eb3f..02491a37a6 100644 --- a/en/device-dev/subsystems/Readme-EN.md +++ b/en/device-dev/subsystems/Readme-EN.md @@ -80,7 +80,7 @@ - [syspara Module](subsys-boot-syspara.md) - [FAQs](subsys-boot-faqs.md) - [Reference](subsys-boot-ref.md) -- [Test](subsys-testguide-test.md) +- [Test Case Development](subsys-testguide-test.md) - DFX - [DFX Overview](subsys-dfx-overview.md) - [HiLog Development](subsys-dfx-hilog-rich.md) @@ -95,8 +95,9 @@ - [HiSysEvent Tool Usage](subsys-dfx-hisysevent-tool.md) - [HiDumper Development](subsys-dfx-hidumper.md) - [HiChecker Development](subsys-dfx-hichecker.md) + - [FaultLogger Development](subsys-dfx-faultlogger.md) - R&D Tools - [bytrace](subsys-toolchain-bytrace-guide.md) - [hdc\_std](subsys-toolchain-hdc-guide.md) - [hiperf](subsys-toolchain-hiperf.md) -- [XTS](subsys-xts-guide.md) \ No newline at end of file +- [XTS Test Case Development](subsys-xts-guide.md) \ No newline at end of file diff --git a/en/device-dev/subsystems/figure/process_crash_handling.png b/en/device-dev/subsystems/figure/process_crash_handling.png new file mode 100644 index 0000000000000000000000000000000000000000..786a6a535d8ccafb9819fe21f7225c875c975144 GIT binary patch literal 56322 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

UvJv;dwzC>a#);#a3}lnnus0M|oksx!n}`{n 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 literal 0 HcmV?d00001 diff --git a/en/device-dev/subsystems/subsys-dfx-faultlogger.md b/en/device-dev/subsystems/subsys-dfx-faultlogger.md new file mode 100644 index 0000000000..8693b997de --- /dev/null +++ b/en/device-dev/subsystems/subsys-dfx-faultlogger.md @@ -0,0 +1,268 @@ +# FaultLogger Development + + +## Overview + + +### Function + +FaultLogger is a maintenance and debugging log framework provided by OpenHarmony. It enables unified detection, log collection, log storage, and log reporting for application, ability, and system service process crashes. + +FaultLogger is responsible for fault recording of OpenHarmony. It runs on the following two components based on the service object: + +- HiView: serves functional modules at the application layer and native layer. It manages various fault information in the system and provides APIs for modules to query faults. + +- FaultLoggerd: serves the crash process. It collects information about abnormal daemon processes in C/C++ and obtains the process call stack. + +The following figure shows the process of handling a process crash based on the FaultLogger service. + + **Figure 1** Process crash handling flowchart + +![process_crash_handling](figure/process_crash_handling.png) + +1. After the signal processor is installed, the **DFX_SignalHandler** function detects and responds to the process crash exception signal. + +2. **SignalHandler** forks a child process after detecting the exception signal and runs **ProcessDump** to dump the stack information of the crashed process and thread. + +3. **ProcessDump** then writes a log to the temporary storage directory in FaultLoggerd, generating a full crash log. + +4. FaultLoggerd reports the fault through the **AddFaultLog()** API provided by HiView. HiView handles the fault, generates a simple crash log, and reports a HiSysEvent. + +With this design, a small-system with limited resources can obtain logs for locating crash faults as long as FaultLoggerd is deployed. + + +### Use Cases + +FaultLoggerd provides a lightweight approach for you to locate crash or suspension problems during development and testing. + +It is applicable to the following scenarios: + + **Table 1** Application scenarios of the Faultloggerd module + +| Scenario| Tool| Usage| +| -------- | -------- | -------- | +| To understand the function call sequence| DumpCatcher API | See [Using DumpCatcher to Obtain the Call Stack](#using-dumpcatcher-to-obtain-the-call-stack).| +| Application suspension or high CPU usage| ProcessDump | See [Using ProcessDump to Obtain the Call Stack](#using-processdump-to-obtain-the-call-stack).| +| Signal crash not handled by the process| Crash log and addr2line tool| See [Locating Faults Based on Crash Logs](#locating-faults-based-on-crash-logs).| + + +## Using DumpCatcher to Obtain the Call Stack + + +### Available APIs + +DumpCatcher can capture the call stack of a specified process (thread) on OpenHarmony. + + Table 2 DumpCatcher APIs + +| Class| API| Description| +| -------- | -------- | -------- | +| DfxDumpCatcher | bool DumpCatch(const int pid, const int tid, std::string& msg) | Return value:
**true**: Back trace is successful. Related information is stored in the **msg** string object.
**false**: Back trace failed.
Input arguments:
**pid**: target process ID.
**tid**: target thread ID. If all threads in the process need to be back traced, set **tid** to **0**.
Output argument:
**msg**: return message. If back trace is successful, the call stack information is returned through **msg**.| + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
+> If the PID that calls this API is different from the target PID, the caller must be the **system** or **root** user. To capture the call stack of a process that does not belong to the current user group, ensure that you have permissions to read **/proc/pid/maps** and implement **ptrace** on the peer process. + + +### Development Example + + +You can use DumpCatcher to obtain the call stack of a specified process (thread) in your applications. The following uses the **dumpcatcherdemo** module as an example to describe how to use the DumpCatcher API to obtain the call stack. + + +1. Add the DumpCatcher dependency to the build file. Take /base/hiviewdfx/faultloggerd/example/BUILD.gn as an example. Add the **dfx_dump_catcher.h** file path to **include_dirs** and add the required **//base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher:lib_dfx_dump_catcher** module to **deps**. + + ``` + import("//base/hiviewdfx/faultloggerd/faultloggerd.gni") + import("//build/ohos.gni") + + config("dumpcatcherdemo_config") { + visibility = [ ":*" ] + + include_dirs = [ + ".", + "//utils/native/base/include", + "//base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher/include/", # Add the path of the dump_catcher header file. + ] + } + + ohos_executable("dumpcatcherdemo") { sources = [ "dump_catcher_demo.cpp" ] configs = [ ":dumpcatcherdemo_config" ] deps = [ "//base/hiviewdfx/faultloggerd/interfaces/innerkits/dump_catcher:lib_dfx_dump_catcher", # Add the DumpCatcher module dependency. "//utils/native/base:utils", ] external_deps = [ "hilog_native:libhilog" ] install_enable = true part_name = "faultloggerd" subsystem_name = "hiviewdfx" + } + ``` + +2. Define the header file. Take **/base/hiviewdfx/faultloggerd/example/dump_catcher_demo.h** as an example. In the sample code, the function of the stack depth test is called to construct a call stack with a specified depth. + + ``` + #ifndef DUMP_CATCHER_DEMO_H + #define DUMP_CATCHER_DEMO_H + + #include + + #define NOINLINE __attribute__((noinline)) + + // Define the macro function to automatically generate a function call chain. + #define GEN_TEST_FUNCTION(FuncNumA, FuncNumB) \ + __attribute__((noinline)) int TestFunc##FuncNumA() \ + { \ + return TestFunc##FuncNumB(); \ + } + + // Call the function of the stack depth test. + int TestFunc0(void); + int TestFunc1(void); + int TestFunc2(void); + int TestFunc3(void); + int TestFunc4(void); + int TestFunc5(void); + int TestFunc6(void); + int TestFunc7(void); + int TestFunc8(void); + int TestFunc9(void); + int TestFunc10(void); + + #endif // DUMP_CATCHER_DEMO_H + ``` + +3. Call the **DumpCatch** API in the source file. Take **/base/hiviewdfx/faultloggerd/example/dump_catcher_demo.cpp** as an example. Include the **dfx_dump_catcher.h** file, declare the **DfxDumpCatcher** object, use the macro function to construct a function call chain, call the **DumpCatch** method, and pass the required process ID and thread ID of the call stack into this method. + + ``` + #include "dump_catcher_demo.h" + + #include + #include + #include + // Include the dfx_dump_catcher.h file. + #include "dfx_dump_catcher.h" + using namespace std; + + NOINLINE int TestFunc10(void) + { + OHOS::HiviewDFX::DfxDumpCatcher dumplog; + string msg = ""; + bool ret = dumplog.DumpCatch(getpid(), gettid(), msg); // Call the DumpCatch API to obtain the call stack. + if (ret) { + cout << msg << endl; + } + return 0; + } + + // Use the macro function to automatically generate a function call chain. + GEN_TEST_FUNCTION(0, 1) + GEN_TEST_FUNCTION(1, 2) + GEN_TEST_FUNCTION(2, 3) + GEN_TEST_FUNCTION(3, 4) + GEN_TEST_FUNCTION(4, 5) + GEN_TEST_FUNCTION(5, 6) + GEN_TEST_FUNCTION(6, 7) + GEN_TEST_FUNCTION(7, 8) + GEN_TEST_FUNCTION(8, 9) + GEN_TEST_FUNCTION(9, 10) + + int main(int argc, char *argv[]) + { + TestFunc0(); + return 0; + } + ``` + + +## Using ProcessDump to Obtain the Call Stack + + +### Tool Description + +ProcessDump is a command line interface (CLI) based tool for capturing call stacks on OpenHarmony. It uses the **-p** and **-t** parameters to specify the process and thread. After the command is executed, the thread stack information of the specified process is displayed in the CLI window. + + **Table 3** Usage of the CLI-based ProcessDump + +| Tool| Path| Command| Description| +| -------- | -------- | -------- | -------- | +| processdump | /system/bin | - processdump -p [pid]
- processdump -p [pid] -t [tid] | **Arguments:**
**- -p [pid]**: prints stack information for all threads of the specified process.
**- -p [pid] -t [tid]**: prints information for the specified thread of the specified process.
**Return value:**
If the stack information is parsed successfully, the information is displayed in the standard output. If the stack information fails to be parsed, error information is displayed.| + + +> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
+> This tool must be used by the **root** user, or the caller must have the permission to ptrace the target process and read the smaps of the target process. + + +### Example + +Use ProcessDump to print the call stack of the **hiview** process. + + +``` +# ps -A | grep hiview + 114 ? 00:00:00 hiview +# processdump -p 114 -t 114 +Tid:114, Name:hiview +#00 pc 0000000000089824(00000000b6f44824) /system/lib/ld-musl-arm.so.1(ioctl+68) +#01 pc 000000000002a709(00000000b6c56709) /system/lib/libipc_core.z.so(_ZN4OHOS15BinderConnector11WriteBinderEmPv+16) +#02 pc 000000000002ba75(00000000b6c57a75) /system/lib/libipc_core.z.so(_ZN4OHOS13BinderInvoker18TransactWithDriverEb+224) +#03 pc 000000000002bb37(00000000b6c57b37) /system/lib/libipc_core.z.so(_ZN4OHOS13BinderInvoker13StartWorkLoopEv+22) +#04 pc 000000000002c211(00000000b6c58211) /system/lib/libipc_core.z.so(_ZN4OHOS13BinderInvoker10JoinThreadEb+36) +#05 pc 0000000000038d07(00000000004bcd07) /system/bin/hiview(_ZNSt3__h6vectorINS_9sub_matchINS_11__wrap_iterIPKcEEEENS_9allocatorIS6_EEE8__appendEj+596) +#06 pc 0000000000028655(00000000004ac655) /system/bin/hiview +#07 pc 00000000000c2b08(00000000b6f7db08) /system/lib/ld-musl-arm.so.1(__libc_start_main+116) +#08 pc 00000000000285f4(00000000004ac5f4) /system/bin/hiview +#09 pc 0000000000028580(00000000004ac580) /system/bin/hiview +``` + + +## Locating Faults Based on Crash Logs + +You can locate faults based on the crash stack logs generated by FaultLoggerd. This section describes how to use the addr2line tool to locate a crash fault. + +1. Find a program crash or construct a crash. + For example, insert the following code into your code to trigger an invalid memory access fault (SIGSEGV). + + + ``` + NOINLINE int TriggerSegmentFaultException() + { + printf("test TriggerSegmentFaultException \n"); + // Forcibly convert the type to construct a crash. + int *a = (int *)(&RaiseAbort); + *a = SIGSEGV; + return 0; + } + ``` + +2. Obtain the crash function call stack log. + The process generates a temporary log file in the** /data/log/faultlog/temp** directory due to an exception that is not handled. The naming rule of the temporary log file is as follows: + + + ``` + cppcrash-pid-time + ``` + + The generated call stack is as follows: + + + ``` + Pid:816 + Uid:0 + Process name:./crasher + Reason:Signal:SIGSEGV(SEGV_ACCERR)@0x0042d33d + Fault thread Info: + Tid:816, Name:crasher + r0:0042d33d r1:0000000b r2:1725d4c4 r3:b6f9fa84 + r4:bec97e69 r5:b6fc0268 r6:0042d661 r7:bec97d60 + r8:00000000 r9:00000000 r10:00000000 + fp:bec97d20 ip:00000020 sp:bec97cd0 lr:b6f9fae4 pc:0042d32c + + #00 pc 000000000000332c(000000000042d32c) /data/crasher(TriggerSegmentFaultException+15) + #01 pc 00000000000035c7(000000000042d5c7) /data/crasher(ParseAndDoCrash+277) + #02 pc 0000000000003689(000000000042d689) /data/crasher(main+39) + #03 pc 00000000000c3b08(00000000b6fbbb08) /system/lib/ld-musl-arm.so.1(__libc_start_main+116) + #04 pc 00000000000032f8(000000000042d2f8) /data/crasher(_start_c+112) + #05 pc 0000000000003284(000000000042d284) /data/crasher(_start+32) + ``` + +3. Use the addr2line tool to analyze the call stack. + Then, parse the line number based on the offset address. + + + ``` + root:~/OpenHarmony/out/hi3516dv300/exe.unstripped/hiviewdfx/faultloggerd$ addr2line -e crasher 000332c + base/hiviewdfx/faultloggerd/tools/crasher/dfx_crasher.c:57 + ``` + + The crash is caused by assigning a value to an unwritable area. It is in code line 57 in the **dfx_crasher.c** file. You can modify it to avoid the crash. diff --git a/en/device-dev/subsystems/subsys-testguide-test.md b/en/device-dev/subsystems/subsys-testguide-test.md index e4d4440383..b3def7ee3f 100644 --- a/en/device-dev/subsystems/subsys-testguide-test.md +++ b/en/device-dev/subsystems/subsys-testguide-test.md @@ -1,4 +1,4 @@ -# Test +# Test Case Development OpenHarmony provides a comprehensive auto-test framework for designing test cases. Detecting defects in the development process can improve code quality. This document describes how to use the OpenHarmony test framework. diff --git a/en/device-dev/subsystems/subsys-xts-guide.md b/en/device-dev/subsystems/subsys-xts-guide.md index 8edb14f97e..4fe43850bc 100644 --- a/en/device-dev/subsystems/subsys-xts-guide.md +++ b/en/device-dev/subsystems/subsys-xts-guide.md @@ -1,4 +1,4 @@ -# XTS +# XTS Test Case Development ## Introduction @@ -332,7 +332,7 @@ The HCTest framework is used to support test cases developed with the C language Test suites are built along with version build. The ACTS is built together with the debug version. - >![](../public_sys-resources/icon-note.gif) **NOTE:** + >![](../public_sys-resources/icon-note.gif) **NOTE** >The ACTS build middleware is a static library, which will be linked to the image. @@ -506,6 +506,7 @@ The test cases are developed with the JavaScript language and must meet the prog **Table 5** +

Syntax

Description

diff --git a/en/device-dev/subsystems/subsys.md b/en/device-dev/subsystems/subsys.md index b70f2033ff..27949f654c 100644 --- a/en/device-dev/subsystems/subsys.md +++ b/en/device-dev/subsystems/subsys.md @@ -13,9 +13,9 @@ - **[Telephony](subsys-tel.md)** - **[Security](subsys-security.md)** - **[Startup](subsys-boot.md)** -- **[Test](subsys-testguide-test.md)** +- **[Test Case Development](subsys-testguide-test.md)** - **[DFX](subsys-dfx.md)** - **[R&D Tools](subsys-toolchain.md)** -- **[XTS](subsys-xts-guide.md)** +- **[XTS Test Case Development](subsys-xts-guide.md)** diff --git a/en/device-dev/website.md b/en/device-dev/website.md index f227baec8b..a7191eb01d 100644 --- a/en/device-dev/website.md +++ b/en/device-dev/website.md @@ -35,7 +35,7 @@ - [Burning](quick-start/quickstart-lite-steps-hi3861-burn.md) - [Networking](quick-start/quickstart-lite-steps-hi3861-netconfig.md) - [Debugging and Verification](quick-start/quickstart-lite-steps-hi3861-debug.md) - - [Running](quick-start/quickstart-lite-steps-hi3816-running.md) + - [Running](quick-start/quickstart-lite-steps-hi3861-running.md) - Hi3516 Development Board - [Setting Up the Hi3516 Development Board Environment](quick-start/quickstart-lite-steps-hi3516-setting.md) - [Writing a Hello World Program](quick-start/quickstart-lite-steps-hi3516-application-framework.md) @@ -131,7 +131,7 @@ - [LiteOS Cortex-A](porting/porting-smallchip-kernel-a.md) - [Linux Kernel](porting/porting-smallchip-kernel-linux.md) - Driver Porting - - [Overview](porting/porting-smallchip-driver-overview.md) + - [Porting Overview](porting/porting-smallchip-driver-overview.md) - [Platform Driver Porting](porting/porting-smallchip-driver-plat.md) - [Device Driver Porting](porting/porting-smallchip-driver-oom.md) @@ -357,22 +357,22 @@ - [UART](driver/driver-platform-uart-develop.md) - [WatchDog](driver/driver-platform-watchdog-develop.md) - Platform Driver Usage - - [ADC](driver-platform-adc-des.md) - - [DAC](driver-platform-dac-des.md) - - [GPIO](driver-platform-gpio-des.md) - - [HDMI](driver-platform-hdmi-des.md) - - [I2C](driver-platform-i2c-des.md) - - [I3C](driver-platform-i3c-des.md) - - [MIPI CSI](driver-platform-mipicsi-des.md) - - [MIPI DSI](driver-platform-mipidsi-des.md) - - [PIN](driver-platform-pin-des.md) - - [PWM](driver-platform-pwm-des.md) - - [Regulator](driver-platform-regulator-des.md) - - [RTC](driver-platform-rtc-des.md) - - [SDIO](driver-platform-sdio-des.md) - - [SPI](driver-platform-spi-des.md) - - [UART](driver-platform-uart-des.md) - - [WatchDog](driver-platform-watchdog-des.md) + - [ADC](driver/driver-platform-adc-des.md) + - [DAC](driver/driver-platform-dac-des.md) + - [GPIO](driver/driver-platform-gpio-des.md) + - [HDMI](driver/driver-platform-hdmi-des.md) + - [I2C](driver/driver-platform-i2c-des.md) + - [I3C](driver/driver-platform-i3c-des.md) + - [MIPI CSI](driver/driver-platform-mipicsi-des.md) + - [MIPI DSI](driver/driver-platform-mipidsi-des.md) + - [PIN](driver/driver-platform-pin-des.md) + - [PWM](driver/driver-platform-pwm-des.md) + - [Regulator](driver/driver-platform-regulator-des.md) + - [RTC](driver/driver-platform-rtc-des.md) + - [SDIO](driver/driver-platform-sdio-des.md) + - [SPI](driver/driver-platform-spi-des.md) + - [UART](driver/driver-platform-uart-des.md) + - [WatchDog](driver/driver-platform-watchdog-des.md) - Peripheral Driver Usage - [LCD](driver/driver-peripherals-lcd-des.md) - [Touchscreen](driver/driver-peripherals-touch-des.md) @@ -477,6 +477,7 @@ - [HiSysEvent Tool Usage](subsystems/subsys-dfx-hisysevent-tool.md) - [HiDumper Development](subsystems/subsys-dfx-hidumper.md) - [HiChecker Development](subsystems/subsys-dfx-hichecker.md) + - [FaultLogger Development](subsystems/subsys-dfx-faultlogger.md) - Featured Topics - HPM Part - [HPM Part Overview](hpm-part/hpm-part-about.md) @@ -517,7 +518,7 @@ - [Development Example for Peripheral Drivers](guide/device-outerdriver-demo.md) - Debugging - - [Test](subsystems/subsys-testguide-test.md) + - [Test Case Development](subsystems/subsys-testguide-test.md) - Debugging Tools - [bytrace](subsystems/subsys-toolchain-bytrace-guide.md) - [hdc\_std](subsystems/subsys-toolchain-hdc-guide.md) diff --git a/en/website.md b/en/website.md index aba19ae3c2..9cf5b09520 100644 --- a/en/website.md +++ b/en/website.md @@ -7,12 +7,11 @@ - [OpenHarmony v3.1 Release (2022-03-30)](release-notes/OpenHarmony-v3.1-release.md) - [OpenHarmony v3.1 Beta (2021-12-31)](release-notes/OpenHarmony-v3.1-beta.md) - [OpenHarmony v3.0.1 LTS (2022-01-12)](release-notes/OpenHarmony-v3.0.1-LTS.md) -- [OpenHarmony v3.0 LTS (2021-09-30)](release-notes/OpenHarmony-v3.0-LTS.md) - + - [OpenHarmony v3.0 LTS (2021-09-30)](release-notes/OpenHarmony-v3.0-LTS.md) + - OpenHarmony 2.x Releases - [OpenHarmony v2.2 beta2 (2021-08-04)](release-notes/OpenHarmony-v2.2-beta2.md) - - [OpenHarmony 2.0 Canary (2021-06-01)](release-notes/OpenHarmony-2-0-Canary.md) - + - [OpenHarmony 2.0 Canary (2021-06-01)](release-notes/OpenHarmony-2-0-Canary.md) - OpenHarmony 1.x Releases - [OpenHarmony v1.1.4 LTS (2022-02-11)](release-notes/OpenHarmony-v1-1-4-LTS.md) - [OpenHarmony v1.1.3 LTS (2021-09-30)](release-notes/OpenHarmony-v1-1-3-LTS.md) diff --git a/zh-cn/device-dev/quick-start/Readme-CN.md b/zh-cn/device-dev/quick-start/Readme-CN.md index 3ba43059da..201084420a 100644 --- a/zh-cn/device-dev/quick-start/Readme-CN.md +++ b/zh-cn/device-dev/quick-start/Readme-CN.md @@ -12,7 +12,7 @@ - [烧录](quickstart-ide-lite-steps-hi3861-burn.md) - [联网](quickstart-ide-lite-steps-hi3861-netconfig.md) - [调试验证](quickstart-ide-lite-steps-hi3861-debug.md) - - [运行](quickstart-ide-lite-steps-hi3816-running.md) + - [运行](quickstart-ide-lite-steps-hi3861-running.md) - Hi3516开发板 - [编写“Hello World”程序](quickstart-ide-lite-steps-hi3516-application-framework.md) - [编译](quickstart-ide-lite-steps-hi3516-building.md) @@ -32,7 +32,7 @@ - [烧录](quickstart-lite-steps-hi3861-burn.md) - [联网](quickstart-lite-steps-hi3861-netconfig.md) - [调试验证](quickstart-lite-steps-hi3861-debug.md) - - [运行](quickstart-lite-steps-hi3816-running.md) + - [运行](quickstart-lite-steps-hi3861-running.md) - Hi3516开发板 - [安装Hi3516开发板环境](quickstart-lite-steps-hi3516-setting.md) - [编写“Hello World”程序](quickstart-lite-steps-hi3516-application-framework.md) diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3816-running.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-running.md similarity index 100% rename from zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3816-running.md rename to zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861-running.md diff --git a/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861.md b/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861.md index 4266d6e5ea..c5cbefed3f 100644 --- a/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861.md +++ b/zh-cn/device-dev/quick-start/quickstart-lite-steps-hi3861.md @@ -14,4 +14,4 @@ - **[调试验证](quickstart-lite-steps-hi3861-debug.md)** -- **[运行](quickstart-lite-steps-hi3816-running.md)** \ No newline at end of file +- **[运行](quickstart-lite-steps-hi3861-running.md)** \ No newline at end of file diff --git a/zh-cn/device-dev/website.md b/zh-cn/device-dev/website.md index 891bdd451a..38e960f2ad 100644 --- a/zh-cn/device-dev/website.md +++ b/zh-cn/device-dev/website.md @@ -15,7 +15,7 @@ - [烧录](quick-start/quickstart-ide-lite-steps-hi3861-burn.md) - [联网](quick-start/quickstart-ide-lite-steps-hi3861-netconfig.md) - [调试验证](quick-start/quickstart-ide-lite-steps-hi3861-debug.md) - - [运行](quick-start/quickstart-ide-lite-steps-hi3816-running.md) + - [运行](quick-start/quickstart-ide-lite-steps-hi3861-running.md) - Hi3516开发板 - [编写“Hello World”程序](quick-start/quickstart-ide-lite-steps-hi3516-application-framework.md) - [编译](quick-start/quickstart-ide-lite-steps-hi3516-building.md) @@ -35,7 +35,7 @@ - [烧录](quick-start/quickstart-lite-steps-hi3861-burn.md) - [联网](quick-start/quickstart-lite-steps-hi3861-netconfig.md) - [调试验证](quick-start/quickstart-lite-steps-hi3861-debug.md) - - [运行](quick-start/quickstart-lite-steps-hi3816-running.md) + - [运行](quick-start/quickstart-lite-steps-hi3861-running.md) - Hi3516开发板 - [安装Hi3516开发板环境](quick-start/quickstart-lite-steps-hi3516-setting.md) - [编写“Hello World”程序](quick-start/quickstart-lite-steps-hi3516-application-framework.md) -- GitLab