【问题标题】:What is wrong with my code? I get a "Bus Error"我的代码有什么问题?我收到“总线错误”
【发布时间】:2011-07-10 16:07:50
【问题描述】:

我正在尝试读取包含原始音频的文件并使用FLAC 对其进行编码。当我运行程序时,我得到一个“总线错误”。有什么问题吗?
我正在使用以下行在 OS X 10.6.8 上编译:

gcc nsFlacEncoder.c -I/opt/local/include -lflac -m32 -o flac_enc

#include "FLAC/stream_encoder.h"
#define READSIZE 40000
char buffer[READSIZE];
FLAC__int32 pcm[READSIZE/2];

FLAC__StreamEncoderWriteStatus write_callback(const FLAC__StreamEncoder *encoder, const  FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
{
    FILE * fp;
    fp = fopen("rec.flac","rw");
    fwrite(buffer, 1, bytes, fp);
    fclose(fp);
    return 0;
}

int rawToFlac()
{
    FLAC__bool ok = true;
    FLAC__StreamEncoder *encoder = 0;
    FLAC__StreamEncoderInitStatus init_status;
    unsigned sample_rate = 16000;
    unsigned channels = 1;
    unsigned bps = 16;

    if((encoder=FLAC__stream_encoder_new()) == NULL){
        printf("Error!");
        return 1;
    }

    ok &= FLAC__stream_encoder_set_verify(encoder, true);
    ok &= FLAC__stream_encoder_set_compression_level(encoder, 5);
    ok &= FLAC__stream_encoder_set_channels(encoder, channels);
    ok &= FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
    ok &= FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
    ok &= FLAC__stream_encoder_set_total_samples_estimate(encoder, READSIZE);

    if(ok){
        init_status = FLAC__stream_encoder_init_stream(encoder, &write_callback, NULL, NULL, NULL, /*client_data=*/NULL);
        if(init_status != FLAC__STREAM_ENCODER_INIT_STATUS_OK){
            printf("Encoder not initiated");
            return 1;
        }
    }

    if(ok){
        while(ok)
        {       
            /* convert the packed little-endian 16-bit PCM samples from WAVE into an interleaved FLAC__int32 buffer for libFLAC */
            size_t i;
            for(i = 0; i < 20000; i++) {
                /* inefficient but simple and works on big- or little-endian machines */
                pcm[i] = (FLAC__int32)(((FLAC__int16)(FLAC__int8)buffer[2*i+1] << 8) | (FLAC__int16)buffer[2*i]);
            }
            /* feed samples to encoder */
            ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, 20000);
        }
    }

    ok &= FLAC__stream_encoder_finish(encoder);
    printf("Finished.");

    FLAC__stream_encoder_delete(encoder);   
    return 0;
}

int main()
{

    FILE *file;
    file = fopen("recording","rb");
    fread(buffer,2, 20000, file);
    rawToFlac();
    fclose(file);
    return 0;
}

运行 gdb flac_enc 给了我这个:

warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/bitmath.o" - no debug information available for "bitmath.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/bitreader.o" - no debug information available for "bitreader.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/bitwriter.o" - no debug information available for "bitwriter.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/cpu.o" - no debug information available for "cpu.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/crc.o" - no debug information available for "crc.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/fixed.o" - no debug information available for "fixed.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/format.o" - no debug information available for "format.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/lpc.o" - no debug information available for "lpc.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/md5.o" - no debug information available for "md5.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/memory.o" - no debug information available for "memory.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/metadata_iterators.o" - no debug information available for "metadata_iterators.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/metadata_object.o" - no debug information available for "metadata_object.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/stream_decoder.o" - no debug information available for "stream_decoder.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/stream_encoder.o" - no debug information available for "stream_encoder.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/stream_encoder_framing.o" - no debug information available for "stream_encoder_framing.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/window.o" - no debug information available for "window.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_decoder_aspect.o" - no debug information available for "ogg_decoder_aspect.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_encoder_aspect.o" - no debug information available for "ogg_encoder_aspect.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_helper.o" - no debug information available for "ogg_helper.c".
warning: Could not find object file "/Users/benski/Desktop/flac-1.2.1/src/libFLAC/.libs/ogg_mapping.o" - no debug information available for "ogg_mapping.c".

这很奇怪,因为我的系统上没有用户“benski”。但我确信 FLAC 库已正确安装,因为 example programs 可以完美运行。

【问题讨论】:

  • 你的巴士有问题。
  • 错误可能在这一行:'ok = FLAC__stream_encoder_process_interleaved(encoder, pcm, 20000);'我似乎无法确定,因为我得到的只是“总线错误”
  • @Kerrek SB:我尝试逐块注释代码。错误是在包含FLAC__stream_encoder_process_interleaved 的块中。您是否看到任何明显的错误?
  • 不,但我不知道那个图书馆。谁给你的错误?它似乎不是来自你自己的代码,所以你没有做足够的错误检查,我会说。如果你注释掉那一行,错误会消失吗?
  • 您是否正在使用 PowerPC 机器在 MacOS X 上工作?该库由用户“benski”编译,但您没有源代码。这只是一个警告;这意味着您将无法单步执行库代码并查看源代码行。这可能无关紧要,除非 SIGBUS 出现在库函数中。

标签: c sigbus


【解决方案1】:

main() 中,您不检查文件是否已成功打开。问题可能在于您在fread() 操作中使用了空指针。同样,在write_callback() 函数中,您的代码显示了无敌假设。 (另外,如果你的回调被多次调用,第二次调用会覆盖第一次调用产生的数据。然而,这是一个不同的问题。)

您不会检查fread() 读取了多少个 2 字节单元。你也不检查fwrite()写了多少数据——成功了吗?

您应该能够使用gdb 或类似的调试器来查看故障发生的位置。

您也可以使用valgrind 来发现问题。

您不需要ifwhile in:

if (ok)
{
    while (ok)
    {
        ...
    }
}

单独的循环就足够了;如果ok 在第一个周期为假,它将被执行零次。如果在while 循环之后和if 结束之前有一个语句,那么两者都是必要的。

通常,当您尝试访问未对齐的数据对象时,RISC 芯片上会发生 SIGBUS(总线错误)。目前尚不清楚哪一行可能导致此代码中的问题。尽管前面有关于“空指针”的评论,但它通常以 SIGSEGV(分段违规)而不是 SIGBUS 告终。

【讨论】:

  • 感谢您指出我的错误。我修好了它们,它奏效了。 :)
【解决方案2】:

你可以通过说来查看核心文件

gdb <executable name> <corefile name> 

然后说“在哪里”查看回溯。这将帮助您查看失败的原因(但正如 @JohnathanLeffler 所指出的,您有几个可以通过检查发现的错误)。

【讨论】:

    【解决方案3】:

    当您期望一些指针可以解决您的问题时,请务必告知更多详细信息,例如 - 哪个平台、编译器、编译器选项(是否启用了任何优化等)。

    AFAIK 如果在未对齐的内存地址上完成某些内存读取或写入操作,则会引发“总线错误”。但是最近没有看到总线错误,因为现代系统(编译器,平台)已经消除了对数据与特定边界对齐的任何硬性和快速需求,除非它是正在为其开发代码的专用硬件架构。

    现在关于你遇到的这个特殊问题 -

    (我假设它是在 Linux 下),所以使用 gcc 的 -g 开关构建代码。

    然后尝试使用 gdb [您的可执行文件]。这应该告诉代码在错误后退出哪个函数/代码行。查看该函数/行/之前和之后的代码!

    我的猜测(疯狂猜测)将是您将样本写入/读取到 pcm[i] 的位置,因为它似乎是 FLAC__int32 类型的用户定义数据。但是,嘿,这可能还很遥远,直到您自己调试。祝你好运!

    【讨论】:

    • 总线错误在 Intel 机器上不会经常发生(如果有的话),但在 SPARC 或 PPC 等 RISC 芯片上会发生。英特尔上未对齐的访问只会减慢机器速度。
    • @Jonathan Leffler - 当然。英特尔架构将允许未对齐的数据访问,但代价是访问该地址并将最终数据字节打包在一起所消耗的额外周期。但是 OP 没有提到任何东西,所以为了让他开始调试这个,我提到了对齐。此外,他没有提到完整的代码(即他的数据类型声明和使用的缓冲区)。
    • SSE 指令是否需要对齐?如果 FLAC 使用 SSE 来加速其实施,我不会感到惊讶。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    • 2016-04-18
    • 2021-12-26
    • 2016-09-05
    相关资源
    最近更新 更多