You need to enable JavaScript to run this app. 如何定位Android端Qt WebAssembly应用的栈溢出问题根源
优惠活动
大模型
产品
解决方案
定价
更多

如何定位Android端Qt WebAssembly应用的栈溢出问题根源

构建环境与运行表现

本次WebAssembly应用的构建工具链为:

  • Emscripten SDK 1.39.8
  • Qt Creator 集成的Qt 5.15.2 静态库
  • Qt WebAssembly 套件

应用跨端运行差异:

  • 桌面环境(Ubuntu 20.04.1 LTS、Firefox 83)运行正常
  • Android 8.1.0 平板搭载的Chrome浏览器加载失败,抛出栈溢出错误后退出

崩溃截图:
WASM应用在Android平板上崩溃,显示栈溢出错误

排查现状

使用Chrome远程调试器定位问题时,因WASM二进制内容被截断,无法导航到二进制内的问题代码段,目前可获取的最完整堆栈跟踪如下:

exception thrown: RuntimeError: abort(stack overflow) at Error
    at jsStackTrace (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1885:17)
    at stackTrace (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1902:16)
    at abort (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1660:44)
    at ___handle_stack_overflow (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1951:7)
    at dlmalloc (http://192.168.1.70:30000/xwatch.wasm:wasm-function[23922]:0x8f5a79)
    at operator new(unsigned long) (http://192.168.1.70:30000/xwatch.wasm:wasm-function[23014]:0x8e2d73)
    at AppWindow::AppWindow(QWidget*) (http://192.168.1.70:30000/xwatch.wasm:wasm-function[438]:0xfb31)
    at main (http://192.168.1.70:30000/xwatch.wasm:wasm-function[437]:0xf9b2)
    at Module._main (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:12207:32)
    at callMain (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:13474:15),RuntimeError: abort(stack overflow) at Error
    at jsStackTrace (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1885:17)
    at stackTrace (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1902:16)
    at abort (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1660:44)
    at ___handle_stack_overflow (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1951:7)
    at dlmalloc (http://192.168.1.70:30000/xwatch.wasm:wasm-function[23922]:0x8f5a79)
    at operator new(unsigned long) (http://192.168.1.70:30000/xwatch.wasm:wasm-function[23014]:0x8e2d73)
    at AppWindow::AppWindow(QWidget*) (http://192.168.1.70:30000/xwatch.wasm:wasm-function[438]:0xfb31)
    at main (http://192.168.1.70:30000/xwatch.wasm:wasm-function[437]:0xf9b2)
    at Module._main (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:12207:32)
    at callMain (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:13474:15)
    at abort (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1666:9)
    at ___handle_stack_overflow (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:1951:7)
    at dlmalloc (http://192.168.1.70:30000/xwatch.wasm:wasm-function[23922]:0x8f5a79)
    at operator new(unsigned long) (http://192.168.1.70:30000/xwatch.wasm:wasm-function[23014]:0x8e2d73)
    at AppWindow::AppWindow(QWidget*) (http://192.168.1.70:30000/xwatch.wasm:wasm-function[438]:0xfb31)
    at main (http://192.168.1.70:30000/xwatch.wasm:wasm-function[437]:0xf9b2)
    at Module._main (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:12207:32)
    at callMain (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:13474:15)
    at doRun (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:13535:23)
    at eval (eval at completeLoadEmscriptenModule (http://192.168.1.70:30000/qtloader.js:443:14), <anonymous>:13546:7)

当前怀疑问题出在AppWindow构造函数,对应代码如下:

AppWindow::AppWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::AppWindow) {
  ui->setupUi(this);
  lapCircle = new LapCircle(this);
  lapCircle->resize(512, 512);
  lapCircle->move(0,0);
  ui->verticalLayout->insertWidget(0, lapCircle);
  updateTimer = new QTimer(this);
  updateTimer->setTimerType(Qt::TimerType::CoarseTimer);
  currentTimeMS = 0;
  uiFont = QFont("IBM Plex Sans");
  setFont(uiFont);
  isVisuallyStopped = false;
  lastDeadlineTimerValue = 0;
  updateTimer->setInterval(2);
  connect(updateTimer, &QTimer::timeout, this, [&](){
    if (!isVisuallyStopped) {
      currentTimeMS += QDeadlineTimer::current().deadline() - lastDeadlineTimerValue;
      updateTimeLabel();
      lastDeadlineTimerValue = QDeadlineTimer::current().deadline();
    }
  });
  connect(ui->btnStart, &QPushButton::clicked, this, [&]() {
    currentTimeMS += (lastDeadlineTimerValue - QDeadlineTimer::current().deadline());
    isVisuallyStopped = false;
    updateTimer->start();
  });
  connect(ui->btnStop, &QPushButton::clicked, this, [&]() {
    isVisuallyStopped = true;
    updateTimer->stop();
  });
  connect(ui->btnReset, &QPushButton::clicked, this, [&]() {
    currentTimeMS = 0;
    updateTimeLabel();
  });
}
定位WASM二进制内问题代码的操作步骤

1. 重新编译带完整调试信息的二进制

  • 编译时追加-g参数保留完整调试符号,关闭过度代码裁剪和断言关闭参数,确保函数名、行号映射信息完整
  • 针对移动端栈空间不足的常见问题,链接阶段手动调整栈大小参数,追加-s TOTAL_STACK=64MB配置:Emscripten 1.39.8版本在移动端的默认栈配置远小于桌面端,桌面端通常分配5MB以上栈空间,移动端默认仅为1MB左右,这是同二进制跨端运行表现差异的核心诱因
  • 配置静态资源服务器对WASM文件返回正确的application/wasm MIME类型,避免Chrome安全策略截断二进制内容,导致远程调试无法加载完整符号表

2. 远程调试定位代码位置

  • 加载带源码映射的完整WASM文件后,直接在调试器的函数列表中检索AppWindow::AppWindow,即可直接跳转到对应的C++代码行
  • 注意:堆栈中显示在dlmalloc函数内触发栈溢出,并非代表内存分配操作越界写到了栈上,而是此时栈指针已经逼近分配的栈边界,dlmalloc执行过程中产生的少量栈上临时变量刚好越过阈值,被Emscripten的栈溢出监控捕获,实际的栈空间消耗来自之前的函数调用链

3. 快速锁定触发点

逐行注释构造函数内的内存分配代码,重新编译部署后验证崩溃点的变化:

  • 首先注释lapCircle = new LapCircle(this)代码行,若崩溃消失则说明LapCircle类的构造函数内存在超大栈上局部变量(比如大尺寸数组),触发了栈空间不足
  • 检查Ui::AppWindow的setupUi逻辑,确认是否存在布局定义的大尺寸控件在栈上初始化,而非堆分配
    注:你当前代码中设置的updateTimer->setInterval(2)配置只会导致定时器刷新频率过高,和本次栈溢出崩溃没有关联

内容的提问来源于stack exchange,提问作者edition

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.13 06:45:04