MNN icon indicating copy to clipboard operation
MNN copied to clipboard

mnn版本为2.7.0的静态库在windows平台内存异常问题

Open feixuedudiao opened this issue 2 years ago • 5 comments

具体的堆栈信息如下: CONTEXT: (.ecxr) eax=000000e5 ebx=47031e2c ecx=00000008 edx=595a854a esi=00000100 edi=47031e1c eip=3e7b37a4 esp=42d2e7cc ebp=42d2e858 iopl=0 nv up ei pl nz na po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202 nce_alg!MNNC3ToFloatRGBA+0x34: 3e7b37a4 f30f1141f8 movss dword ptr [ecx-8],xmm0 ds:002b:00000000=???????? Resetting default scope

EXCEPTION_RECORD: (.exr -1) ExceptionAddress: 3e7b37a4 (nce_alg!MNNC3ToFloatRGBA+0x00000034) ExceptionCode: c0000005 (Access violation) ExceptionFlags: 00000000 NumberParameters: 2 Parameter[0]: 00000001 Parameter[1]: 00000000 Attempt to write to address 00000000

PROCESS_NAME: Yealink Meeting.exe

WRITE_ADDRESS: 00000000

ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p 0x%p %s

EXCEPTION_CODE_STR: c0000005

EXCEPTION_PARAMETER1: 00000001

EXCEPTION_PARAMETER2: 00000000

STACK_TEXT:
42d2e858 3e76f7bc 42d2e884 42d2e878 118dbac8 nce_alg!MNNC3ToFloatRGBA+0x34 42d2e89c 3e76f50c 406b4648 406b4258 406b4648 nce_alg!MNN::CV::ImageProcess::convert+0x24c 42d2e928 3e74fd93 4911fea0 00000140 000000b4 nce_alg!MNN::CV::ImageProcess::convert+0x1ec 从解析及分析定位的结论看看是在函数MNNC3ToFloatRGBA函数中出现了空bufffer,应该是在函数的source和dest指针,但不能定位为何出现这个问题,我看源代码中source和dest指针是通过下面代码实现的 std::unique_ptr<Tensor> input(createImageTensor(halide_type_of<uint8_t>(), iw, ih, ic, (void*)source)), output(createImageTensor(type, ow, oh, oc, dest)); 目前只能分析这里,还请教大佬帮忙看看,谢谢。

feixuedudiao avatar Dec 27 '23 08:12 feixuedudiao

这个看着是 dest 为空,检查下 convert 的目标指针是否为空吧

jxt1234 avatar Dec 27 '23 11:12 jxt1234

图片 目标指针已经有判空。

feixuedudiao avatar Jan 12 '24 01:01 feixuedudiao

图片

feixuedudiao avatar Jan 12 '24 01:01 feixuedudiao

已经对dest指针做判空处理,但还是出现。 if(NULL == kv.second) return NCE_FAILED;

        MNN::Tensor *pTensor = kv.second;
        NCE_S32 pWidth = pTensor->width();
        NCE_S32 pHeight = pTensor->height();
        NCE_S32 pChn    = pTensor->channel();
        NCE_S32 imgSz = pWidth * pHeight;
        NCE_U8 * data = (NCE_U8*)pTensor->host<void>();

        if (data == NULL)
        {
            return NCE_FAILED;
        }
     ...

pprocessors->convert(image_datas.image, image_datas.image_attr.u32Width, image_datas[count].image_attr.u32Height, 0, kv.second);

feixuedudiao avatar Jan 12 '24 08:01 feixuedudiao

ErrorCode CPUImageProcess::onExecute(const std::vector<Tensor > &inputs, const std::vector<Tensor > &outputs) { if (0 == mStride) { mStride = iw * ic; } auto source = inputs[0]->host<uint8_t>(); void dest = nullptr; CV::Point points[2]; auto destBytes = dtype.bytes(); int tileCount = UP_DIV(ow, CACHE_SIZE); const int regions = nullptr; if (draw) { // change input to output dest = source; oh = inputs[1]->length(0); ow = iw; oc = ic; destBytes = inputs[0]->getType().bytes(); // draw one tileCount = 1; // src is color samplerDest = inputs[2]->host<uint8_t>(); // get region info ptr regions = inputs[1]->host(); } else { dest = outputs[0]->host(); }

if (nullptr == dest)
    return INPUT_DATA_ERROR;

for (int i = 0; i < oh; ++i) {
    int dy = draw ? regions[3 * i] : i;
    auto dstY = (uint8_t*)dest + dy * destBytes * ow * oc;
    for (int tIndex = 0; tIndex < tileCount; ++tIndex) {
        int xStart    = tIndex * CACHE_SIZE;
        int count     = std::min(CACHE_SIZE, ow - xStart);
        if (draw) {
            xStart = regions[3 * i + 1];
            count = regions[3 * i + 2] - xStart + 1;
        }
        auto dstStart = dstY + destBytes * oc * xStart;

        if (!blitFloat) {
            blitDest = dstStart;
        }
        if (!blitter) {
            samplerDest = blitDest;
        }

        // Sample
        if (!draw) {
            // Compute position
            points[0].fX = xStart;
            points[0].fY = dy;

            points[1].fX = xStart + count;
            points[1].fY = dy;
            transform.mapPoints(points, 2);
            float deltaY = points[1].fY - points[0].fY;
            float deltaX = points[1].fX - points[0].fX;

            int sta = 0;
            int end = count;

            // FUNC_PRINT(sta);
            if (wrap == WrapType_ZERO) {
                // Clip: Cohen-Sutherland
                auto clip    = _computeClip(points, iw, ih, transformInvert, xStart, count);
                sta          = clip.first;
                end          = clip.second;
                points[0].fX = sta + xStart;
                points[0].fY = dy;

                transform.mapPoints(points, 1);
                if (sta != 0 || end < count) {
                    if (ic > 0) {
                        if (sta > 0) {
                            ::memset(samplerDest, paddingValue, ic * sta);
                        }
                        if (end < count) {
                            ::memset(samplerDest + end * ic, paddingValue, (count - end) * ic);
                        }
                    } else {
                        // TODO, Only support NV12 / NV21
                        ::memset(samplerDest, paddingValue, count);
                        ::memset(samplerDest + count, 128, UP_DIV(count, 2) * 2);
                    }
                }
            }
            points[1].fX = (deltaX) / (float)(count);
            points[1].fY = (deltaY) / (float)(count);

            sampler(source, samplerDest, points, sta, end - sta, count, iw, ih, mStride);
        }
        // Convert format
        if (blitter) {
            blitter(samplerDest, blitDest, count);
        }
        // Turn float
        if (blitFloat) {
            blitFloat(blitDest, (float*)dstStart, mean, normal, count);

上面是onExecute函数的代码,函数void MNNC3ToFloatRGBA(const unsigned char* source, float* dest, const float* mean, const float* normal, size_t count)中的dest指针是通过for循环遍历指针指代进行的,如果在convert中的dest为空,这在onExecute函数中就出现异常了。

feixuedudiao avatar Jan 12 '24 08:01 feixuedudiao

Marking as stale. No activity in 60 days.

github-actions[bot] avatar Mar 12 '24 09:03 github-actions[bot]