【问题标题】:Assembly / Neon code crashing组装/霓虹灯代码崩溃
【发布时间】:2014-11-26 22:09:55
【问题描述】:

我正在使用以下代码:

#include <stdlib.h>
#include <fcntl.h>

int main(int argc, char **argv) {
    char *auyvy = malloc(640 * 480 * 2);
    char *ay8 = malloc(640 * 480);

    int fd = open("input.uyvy", O_RDONLY);
    if (fd >= 0) {
        read(fd, auyvy, 640 * 480 * 2);
        close(fd);
    }

    __uyvy_luma_extract(640, 480, auyvy, 640 * 2, ay8, 640);

    fd = open("output.y8", O_RDWR | O_CREAT);
    if (fd >= 0) {
        write(fd, ay8, 640 * 480);
        close(fd);
    }
}

还有两个附加文件: https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/__uyvy_luma_extract.S https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/yuv.inc

我用“gcc -g convert.c __uyvy_luma_extract.S -mfpu=neon”编译

奇怪的是,程序在转换过程中崩溃了。知道我做错了什么吗?

* 首次编辑 * 我已经上传了一个包含各种文件的 zip 文件,以便在 ARM 平台上轻松重现:http://www.gentil.com/tmp/convert.zip

* 第二次编辑 * 我更新了不正确的程序集文件链接。

* 第三次编辑 * gdb 给出以下内容:

Starting program: /home/ai/convert/convert                                      

Program received signal SIGSEGV, Segmentation fault.
0x00008036 in ?? ()
(gdb) bt
#0  0x00008036 in ?? ()
#1  0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38
#2  0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

【问题讨论】:

    标签: assembly neon


    【解决方案1】:

    哦,这个不错。

    如果使用 -marm 构建它可以正常工作,但使用 -mthumb 会中断。 Ubuntu 和 Android 可能对此有不同的默认设置。

    它在 Thumb 模式下中断的原因是汇编函数(始终是非 Thumb)缺少符号的类型规范,因此链接器不知道它需要使用 BLX 指令来调用它拇指码。当程序执行时,汇编函数因此在 Thumb 状态下被错误地调用。此函数的第一个半字 0x47ff 在解释为 Thumb 指令时为 BLX pc,它因不可预知的行为而无效。显然,Cortex内核只是简单地以显而易见的方式执行它,即切换到ARM状态,跳转到PC值(当前指令+Thumb状态下的4),并将下一条(Thumb)指令地址存储在LR中,从而给出似乎只是忽略了 STM 指令。

    解决方法是将此行添加到程序集文件中:

    .type __uyvy_luma_extract, STT_FUNC
    

    【讨论】:

      【解决方案2】:

      您提供了错误的链接。正确的应该是: https://github.com/emrainey/DVP/blob/master/libraries/public/yuv/__uyvy_luma_extract.S

      而且库被窃听了。或者作者假设您使用的是空降序堆栈,而您很可能使用的是全降序堆栈。 将第 39 和 40 行更改为:

      ldr     pY,         [sp, #(11 * 4)]
      ldr     dstStride,  [sp, #(12 * 4)]
      

      无论如何,库在性能方面相当乏善可陈。写得非常业余,会以 NEON 潜在速度的一半运行。

      ================================================ =========================

      编辑:查看 PROLOG 宏,它显示库也推送 lr。这意味着上面的部分没有被窃听。

      该功能应该可以正常工作,尽管不是最佳的。检查以下内容:

      • 内存分配(不太可能)
      • 异常处理(未定义指令异常)

      您的代码因什么异常而崩溃?

      【讨论】:

      • 还是不行:-(我用的是gcc 4.6.3版。你可以在arm设备上试试。
      • 如果我运行 gdb convert,我得到:程序收到信号 SIGSEGV,分段错误。 0x00008036 在?? ()(gdb) bt #0 0x00008036 在?? () #1 0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38 #2 0x000084f2 in __uyvy_luma_extract () at __uyvy_luma_extract.S:38 回溯停止:前一帧与此帧相同(损坏的堆栈?)
      • @gregoiregentil 我没有任何用于测试运行的设备。因此,它在将 ARM 寄存器压入堆栈时崩溃。这是堆栈溢出。检查你的堆栈大小。
      • 更改堆栈大小并不能解决问题。
      • 即使组装功能不是最佳的,我可以向您保证它也没有缺陷。您的系统/进程堆栈是否配置为“全降序”堆栈?崩溃时SP的价值是多少?你启用互通了吗?
      猜你喜欢
      • 1970-01-01
      • 2016-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      相关资源
      最近更新 更多