【问题标题】:Gifflen Fatal Signal 11吉夫伦致命信号 11
【发布时间】:2013-08-07 04:17:35
【问题描述】:

我正在尝试使用一些本机代码来创建 Gif。 我使用油漆绘制图像,创建一些笔画,单击保存,绘制的图像将保存为 JPG 格式。当我单击创建 Gif 时,它会获取所有图像并开始创建 gif。这是我收到致命信号 11 并重新启动应用程序的时候。

我使用本机代码,所以我有崩溃的回溯:

I/DEBUG(95): backtrace:
I/DEBUG(95):     #00  pc 00002a04  /lib/libgifflen.so (NeuQuant::learn()+239)
I/DEBUG(95):     #01  pc 00002b9d  /lib/libgifflen.so (NeuQuant::quantise(DIB*, DIB*, int, int, int)+84)
I/DEBUG(95):     #02  pc 00002d41  lib/libgifflen.so (Java_com_stay_gif_GifEncoder_addFrame+208)
I/DEBUG(95):     #03  pc 0001deb0  /system/lib/libdvm.so (dvmPlatformInvoke+112)
I/DEBUG(95):     #04  pc 0004d103  /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+394)
I/DEBUG(95):     #05  pc 0004f21f  /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+174)
I/DEBUG(95):     #06  pc 000272e0  /system/lib/libdvm.so
I/DEBUG(95):     #07  pc 0002bbe8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
I/DEBUG(95):     #08  pc 0005fb37  /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+374)
I/DEBUG(95):     #09  pc 000670e5  /system/lib/libdvm.so
I/DEBUG(95):     #10  pc 000272e0  /system/lib/libdvm.so
I/DEBUG(95):     #11  pc 0002bbe8  /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+180)
I/DEBUG(95):     #12  pc 0005f871  /system/lib/libdvm.so (dvmCallMethodV(Thread*, Method const*, Object*, bool, JValue*, std::__va_list)+272)
I/DEBUG(95):     #13  pc 000496f3  /system/lib/libdvm.so
I/DEBUG(95):     #14  pc 00048581  /system/lib/libandroid_runtime.so
I/DEBUG(95):     #15  pc 00049637  /system/lib/libandroid_runtime.so (android::AndroidRuntime::start(char const*, char const*)+390)
I/DEBUG(95):     #16  pc 00000dcf  /system/bin/app_process

崩溃的代码:

void NeuQuant::learn()
{

    int i,j,b,g,r;
    int radius,rad,alpha,step,delta,samplepixels;
    //unsigned char *p;
    int *p;
    unsigned char *lim;

    alphadec = 30 + ((samplefac-1)/3);
    p = (int*)thepicture;
    lim = thepicture + lengthcount;
    samplepixels = lengthcount/samplefac;
    delta = samplepixels/ncycles;
    alpha = initalpha;
    radius = initradius;

    rad = radius >> radiusbiasshift;
    if (rad <= 1) rad = 0;
    for (i=0; i<rad; i++)
            radpower[i] = alpha*(((rad*rad - i*i)*radbias)/(rad*rad));

    //fprintf(stderr,"beginning 1D learning: initial radius=%d\n", rad);
    sprintf(s, "samplepixels = %d, rad = %d, a=%d, ad=%d, d=%d", samplepixels, rad, alpha, alphadec, delta);
    __android_log_write(ANDROID_LOG_VERBOSE, "gifflen",s);

    if ((lengthcount%prime1) != 0) step = prime1;
    else {
            if ((lengthcount%prime2) !=0) step = prime2;
            else {
                    if ((lengthcount%prime3) !=0) step = prime3;
                    else step = prime4;
            }
    }

    i = 0;
    while (i < samplepixels)
        {
    /*      b = p[0] << netbiasshift;
            g = p[1] << netbiasshift;
            r = p[2] << netbiasshift;*/
            b = (((*p)) & 0xff) << netbiasshift;
            g = (((*p) >> 8) & 0xff) << netbiasshift;
            r = (((*p) >> 16) & 0xff) << netbiasshift;
            j = contest(b, g, r);
            altersingle(alpha,j,b,g,r); //these crashes
            if (rad) alterneigh(rad,j,b,g,r);   // alter neighbours

            p += step;
            if (p >= (int *)lim) p -= lengthcount;

            i++;
            if (i%delta == 0)
            {
                alpha -= alpha / alphadec;
                radius -= radius / radiusdec;
                rad = radius >> radiusbiasshift;
                if (rad <= 1) rad = 0;
                for (j=0; j<rad; j++)
                    radpower[j] = alpha*(((rad*rad - j*j)*radbias)/(rad*rad));
            }
        }

        //sprintf(s, "final alpha = %f", ((float)alpha)/initalpha);
    //  __android_log_write(ANDROID_LOG_VERBOSE, "gifflen",s);
}

感谢日志,我发现错误发生在 NeuQuant::learn() 中,做了一些调试,它在这条确切的行 b = (((*p)) & 0xff)

崩溃并不总是发生,有时我得到一个 gif 并且一切正常,但有时它在 b = (((*p)) & 0xff) 处崩溃

我做了更多调试,发现当它在 b = (((*p)) & 0xff) 的 30 次检查之后崩溃

有人知道可能是什么问题吗?

【问题讨论】:

  • 可能p 成为无效引用,由于您的指针算法导致分段错误。
  • 我该如何解决这个问题?有没有办法检查“p”以及是否无效停止或类似的东西?

标签: android android-ndk gif fatal-error native-code


【解决方案1】:

我变了:

if (p >= (int *)lim)
    p -= lengthcount;

到:

if (p >= (unsigned int *)lim)
    p = (unsigned int*)thepicture;

而且它现在似乎可以工作了。

【讨论】:

  • 这种做法不正确。它将输出 GIF 的大小放大 30%。我找到了另一个很好的解决方案。我只是从原始 NeuQuant algorythm 复制方法 learn() 的主体并粘贴到 gifflen NeuQuant::learn()
  • 我刚刚用你的代码和上面的代码做了一些测试。我没有看到 GIF 大小的差异。最小的 GIF 大约 1000 KB,在这两种情况下最大的大约 2500 KB。尝试为测试绘制相同的图像,因此尺寸差异最大/小 10%。
  • 你是我的救星。谢谢!
猜你喜欢
  • 2012-09-16
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多