DEV Community

Cover image for Introduction to DevEco Studio for HarmonyOS Next Development: ASan and TSan Detection to Cure Your C++ Phobia
kouwei qing
kouwei qing

Posted on • Edited on

Introduction to DevEco Studio for HarmonyOS Next Development: ASan and TSan Detection to Cure Your C++ Phobia

Introduction to DevEco Studio for HarmonyOS Next Development: ASan and TSan Detection to Cure Your C++ Phobia

1. Background Introduction

Many developers feel intimidated by C++, primarily due to memory operations. Improper memory operations such as array out-of-bounds access, memory leaks, and double-freeing can cause performance issues like high memory consumption,卡顿 (lag), or even program crashes. When an error terminates an app process, error logs are thrown to indicate the crash cause. Developers can analyze these logs—collected automatically by the system as FaultLog—to identify the problematic code. FaultLog includes:

  • App Freeze
  • CPP Crash
  • JS Crash
  • System Freeze
  • ASan
  • TSan

While other tools are commonly used, this article focuses on DevEco Studio's memory and thread debugging tools: ASan (Address Sanitizer) and TSan (Thread Sanitizer), as ArkTS's single-threading and non-shared memory multi-threading often shift complex multi-threading to the C++ layer.

2. ASan Detection

C++ memory issues mainly involve out-of-bounds access, memory leaks, and double-freeing. For performance reasons, compilers and runtime frameworks don’t check memory operations by default. DevEco Studio’s ASan helps detect such issues.

2.1 ASan Configuration

ASan is controlled by ASAN_OPTIONS parameters, which set detection levels, output formats, and error report details. Configure parameters in:

  1. The project’s app.json5 (higher priority)
  2. Run/Debug Configurations
2.1.1 Configuring in app.json5

In AppScope > app.json5:

{
  "app": {
    "appEnvironments": [
      {
        "name": "ASAN_OPTIONS",
        "value": "log_exe_name=true abort_on_error=0 print_cmdline=true" // For reference only
      }
    ],
    ...
  }
}
Enter fullscreen mode Exit fullscreen mode
2.1.2 Configuring in Run/Debug Configurations

Add a configuration named ASAN_OPTIONS with the value: log_exe_name=true abort_on_error=0 print_cmdline=true.

2.1.3 Configurable Parameters
Parameter Default Required Description
log_exe_name true Yes Includes the executable name in memory error logs (non-modifiable).
log_path /dev/asanlog/asan.log No Required for ROM versions < NEXT.0.0.68 (non-modifiable); deprecated in NEXT.0.0.68+.
abort_on_error false Yes Specifies whether to call abort() or _exit() after printing errors:
- false: Use _exit()
- true: Use abort()
strip_path_prefix - No Removes the configured prefix from file paths in error logs (e.g., /data/storage/el1).
detect_stack_use_after_return false No Checks for access to freed stack space:
- true: Enable check
- false: Disable check.
halt_on_error 0 No Determines if the program continues after detecting errors:
- 0: Continue
- 1: Terminate.
malloc_context_size - No Number of call stack layers shown when a memory error occurs.
suppressions "" No Suppresses specified file names.
handle_segv - No Checks for segmentation faults.
handle_sigill - No Checks for SIGILL signals.
quarantine_size_mb 256 No Size of the quarantine area for detecting freed stack space access errors.

2.2 Enabling ASan

Enable ASan in two ways:

  1. In the run/debug window, click Diagnostics and check Address Sanitizer.

  1. Add ASan configuration in AppScope/app.json5.

Note: For dependent native libraries, configure arguments: "-DOHOS_ENABLE_ASAN=ON" in the library’s build-profile.json5 to compile SO files in ASan mode.

When a memory error occurs, ASan logs appear. Click the link in the log to jump to the problematic code. For example, an array out-of-bounds error triggers:

2.3 ASan Error Codes

ASan reports specific error codes with causes:

2.3.1 heap-buffer-overflow
  • Cause/Impact: Out-of-bounds access, leading to security vulnerabilities and crash risks.
  • Fix: Check bounds for known-size collections; validate sizes before accessing dynamic collections.
  • Example:
  int heapBufferOverflow() {
      char *buffer = (char *)malloc(10);
      *(buffer + 11) = 'n'; // Overflow
      *(buffer + 12) = 'n'; // Overflow
      free(buffer);
      return buffer[1];
  }
Enter fullscreen mode Exit fullscreen mode
2.3.2 stack-buffer-underflow
  • Cause/Impact: Access below the buffer bound, risking security and crashes.
  • Fix: Ensure indices are not less than the lower bound.
  • Example:
  int stackBufferUnderflow() {
      int subscript = -1;
      char buffer[42];
      buffer[subscript] = 42; // Underflow
      return 0;
  }
Enter fullscreen mode Exit fullscreen mode
2.3.3 stack-use-after-scope
  • Cause/Impact: Using stack variables outside their scope, risking security and crashes.
  • Fix: Mind variable scoping.
  • Example:
  int *gp;
  bool b = true;
  int stackUseAfterScope() {
      if (b) {
          int x[5];
          gp = x + 1; // Pointer to stack variable
      }
      return *gp; // Use after scope ends
  }
Enter fullscreen mode Exit fullscreen mode
2.3.4 attempt-free-nonallocated-memory
  • Cause/Impact: Freeing non-heap or unallocated memory, risking security and crashes.
  • Fix: Avoid free() on non-heap or unallocated memory.
  • Example:
  int main() {
      int value = 42;
      free(&value); // Free stack variable
      return 0;
  }
Enter fullscreen mode Exit fullscreen mode
2.3.5 double-free
  • Cause/Impact: Freeing memory twice, risking security and crashes.
  • Fix: Initialize pointers to NULL and reset them after freeing.
  • Example:
  int main() {
      int *x = new int[42];
      delete [] x;
      delete [] x; // Double-free
      return 0;
  }
Enter fullscreen mode Exit fullscreen mode
2.3.6 heap-use-after-free
  • Cause/Impact: Accessing freed memory, risking security and crashes.
  • Fix: Implement a free() alternative or destructor to reset pointers.
  • Example:
  #include <stdlib.h>
  int main() {
      int *array = new int[5];
      delete[] array;
      return array[5]; // Use after free
  }
Enter fullscreen mode Exit fullscreen mode

2.4 Additional Notes

  • If any module enables ASan, the entry module must also enable ASan; otherwise, the app will crash on startup with a CPP Crash error.

3. TSan Detection

Another C++ challenge is multi-threading, where unpredictable execution orders complicate debugging. DevEco Studio’s TSan (ThreadSanitizer) detects data races, using a compiler instrumentation module and runtime library.

3.1 Key Application Scenarios

TSan helps identify multi-threading issues:

  • Data Race Detection: Occurs when two or more threads access the same memory without proper synchronization (at least one write), causing unpredictable behavior.
  • Lock Error Detection:
    • Deadlock: Threads wait for each other’s locks, halting execution.
    • Double Unlock: Unlocking an already unlocked lock.
    • Unlock Without Hold: Unlocking a lock not held by the thread.
  • Condition Variable Error Detection:
    • Wait Without Lock: Calling wait() without holding the related lock.
    • Signal/Broadcast Without Lock: Calling signal()/broadcast() without holding the related lock.

3.2 TSan Configuration

Enable TSan in two ways:

  1. In the run/debug window, click Diagnostics and check Thread Sanitizer.

  1. Modify AppScope/app.json5 to add TSan configuration.

Note: For referenced native libraries, configure arguments: "-DOHOS_ENABLE_TSAN=ON" in the library’s build-profile.json5 to compile SO files in TSan mode.

3.3 Enabling TSan

When a thread error occurs during app run/debug, TSan logs appear. Click the link to jump to the problematic code:

TSan reports include:

  • Error type (e.g., data race, deadlock)
  • Memory address
  • Thread info (ID and stack trace)
  • Source code locations and stack traces
  • Context (read/write type, access size)

Note: call_once may trigger false positives. Add __attribute__((no_sanitize("thread"))) before the function to suppress this.

3.4 Additional Notes

  • TSan reduces performance by 5–15x and increases memory usage by 5–10x, potentially affecting features like GPU rendering.
  • ASan and TSan cannot be enabled simultaneously.
  • TSan supports API 12 and above.

4. Summary

This article introduces DevEco Studio’s ASan and TSan tools for debugging C++ memory and thread issues:

  • ASan detects address overflows, memory leaks, and double-freeing.
  • TSan detects data races, lock errors, and condition variable issues.

DevEco Studio’s tooling simplifies C++ development by identifying and resolving complex issues. Familiarizing yourself with these tools empowers you to tackle C++ challenges confidently, eliminating hidden risks through systematic detection.

Top comments (0)