You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pybind11绑定Armadillo矩阵时出现堆损坏的原因及排查思路

Armadillo+pybind11堆内存损坏问题排查求助

我已经研究这个问题两周了,没法在代码库外构造出可复现的样例,因此需要大家的帮助。我暂时不确定问题出在pybind11还是Armadillo,可以排除是Carma的问题,因为错误在没有类型转换的场景下也会发生。

编辑补充:现在确认这是Carma的bug,我已经构造出了可复现的最小样例。

我一直尝试精简出最小可复现样例(MRE)但没有成功。我会在这里说明已知的信息,由于信息不足以复现bug,我最需要的是排查方向的建议。这是一个极难复现的内存损坏错误(堆损坏,Windows fatal exception: code 0xc0000374),触发场景为:未初始化的矩阵A被赋值为一个足够大的矩阵,使得Armadillo需要申请动态内存,在该内存被释放时就会发生崩溃。

我的运行环境为Windows 10,使用Armadillo 10.6.2、pybind11 v2.7.1,编译器为Clang 11。

// mat_container.cpp
#include "mat_container.h"

MatrixContainer::MatrixContainer(size_t d) {
    A = arma::Mat<double>(d, d, arma::fill::eye);
    std::cerr << "filled arma matrix\n";
}

绑定代码如下:

#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>
#include <armadillo>
#include <carma>
#include "mat_container.h"

PYBIND11_MODULE(example, m) {
  py::class_<MatrixContainer>(m, "MC").def(py::init<size_t, bool>())
       .def_readwrite("A", &MatrixContainer::A);
}

触发崩溃只需要在Python中调用example.MC(11),崩溃发生在成员变量(而非赋值的临时变量)的矩阵析构函数释放内存时。崩溃前的Armadillo调试日志如下:

@ __cdecl arma::Mat<double>::~Mat(void) [eT = double] [this = 000001569470DBA0]
Mat::destructor: releasing memory

我尝试构造的MRE中,我复现了完全相同的结构,绑定代码使用的MatrixContainer类也在独立的库中编译,但没能复现bug,我不清楚遗漏了什么配置。

异常特征汇总

  • 仅通过pybind11调用时触发,纯C++环境下不会出现
  • 仅当包含矩阵的类的构造函数放在独立编译的源文件中时触发,构造函数放在头文件中时不会出现
  • 仅当给对象的矩阵成员赋值非单位矩阵(比如np.ones而非np.eye)时触发但该情况仅在我源码中的类上复现,我创建的小型测试类不会出现
  • 仅当A的大小超过Armadillo局部内存阈值、需要申请动态内存时触发
  • 赋值前调用set_size()设置A的大小无法解决问题
  • 该问题看起来是Armadillo特有,仅在Armadillo释放内存时触发(通过ARMA_EXTRA_DEBUG确认),使用vector等其他动态内存分配的类不会出现类似错误

当使用动态内存的A被替换为使用局部内存的矩阵时,会触发崩溃:

mc = MC(11)
mc.A = np.eye(3)

赋值mc.A时崩溃前的Armadillo调试日志如下:

@ void __cdecl arma::Mat<double>::init_warm(arma::uword, arma::uword) [eT = double] [in_n_rows = 3, in_n_cols = 3]
Mat::init(): releasing memory

反向操作则不会触发崩溃,以下代码可以正常运行,A销毁时释放动态内存也不会崩溃:

mc = MC(3)
mc.A = np.eye(11)

如果11x11的A被替换为另一个来自numpy的11x11矩阵,也会触发崩溃,调试日志和第一个无Python赋值的例子一致,为Mat::destructor: releasing memory。从上述示例我推断:当Carma(而非Armadillo直接)构造的动态内存矩阵被赋值给使用局部内存的A时,崩溃不会发生。

更新

目前还在排查中,但看起来错误的触发原因是arma_extra_code处于开启状态(我的MRE中没有开启该配置),问题根源似乎是Carma设置的ARMA_ALIEN_MEM相关函数。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:15:03