dongzhenshen7435 2014-08-15 15:19
浏览 117
已采纳

Go,OpenAL,DirectSound和Heisenbug [关闭]

I've already killed a week trying to solve a mysterious problem in a project of mine and I am out of ideas.

I wrote a Go package intended to play sounds which wraps OpenAL... pretty basic stuff. I got it working on my Xubuntu 14.04 (32-bit), so I booted into Windows (7, also 32-bit) in order to port it... and that's where the problems started.

Whenever I tried to use my audio package, the program crashed with c0000005. I tried to run it through gdb and was surprised to find out that it worked without a problem, it even played my test sound.

Time passed and not knowing what to do, I downloaded the OpenAL Soft source code and started adding printfs - and discovered the exact line it crashed on:

http://repo.or.cz/w/openal-soft.git/blob/HEAD:/Alc/backends/dsound.c#l361

For those lazy to click the link (or if the link stopped working), it's a call to DirectSoundCreate. Running through the debugger again, I saw my prints right before and after the call, and 4 new threads being created between them.

These are the relevant things in the Go file:

package audio

/*
#cgo CFLAGS: -I"../libraries/include"

#cgo windows,386 LDFLAGS: ../libraries/lib/windows/x86/OpenAL32.dll
#cgo windows,amd64 LDFLAGS: ../libraries/lib/windows/x64/OpenAL32.dll
#cgo linux LDFLAGS: -lopenal

#include "audio.h"
*/
import "C"
import (
    "errors"
)

var context *C.ALCcontext

func Init() error {
    context = C.initAudio() // it crashes on this line
    if context == nil {
        return errors.New("could not initialize audio")
    }

    SetActiveListener(NewListener())

    return nil
}

And here's the C file actually making the OpenAL calls:

#include "audio.h"

#include <string.h>
#include <stdio.h>

ALCcontext* initAudio() {
    ALCdevice* device = alcOpenDevice(NULL); // crashes here
    if (device == NULL) {
        return NULL;
    }

    ALCcontext* context = alcCreateContext(device, NULL);
    if (!alcMakeContextCurrent(context)) {
        return NULL;
    }

    return context;
}

Last but not least, if I do the exact same thing in pure C (literally just adding main into the file I posted and calling initAudio), it works.

My question is obvious: What the #@!$ is going on?

edit:

Some other things which might be worth mentioning:

I created a new project completely separate from the previous one, in which I have the two files I posted earlier (with different paths for the linker in the Go file, obviously) and the main Go file which does only one thing: call audio.Init. Regardless of which dll I try (I tried the "official" one from http://openal.org, the precompiled version of OpenAL Soft and two versions I compiled myself, one with MinGW and one with Visual Studio), it behaves the same. I also tried to call runtime.LockOSThread at the start of audio.Init, but it didn't help.

Also, I sent the compiled program to my two friends, one running Windows 8 and one with Windows 7 (both 64-bit). The one with Windows 8 said it worked, the one with 7 said it crashed. However, if we tried to compile it from source on the latter machine, with the 64-bit toolchain, it worked.

edit #2:

I just tried to compile OpenAL Soft from source again - first with Visual Studio and then with MinGW - and then link my independent project I mentioned earlier with the library files (OpenAL32.lib from VS and libOpenAL32.dll.a from MinGW) instead of the DLL directly (since that is... the more correct way I guess?)

The result with VS:

It failed during linking, with the following message:

# command-line-arguments
C:\Users\Milan\AppData\Local\Temp\go-build078751523/audiot/audio.a(_all.o): malf
ormed pe file: unexpected flags 0xe0500020 for PE section .text
audiot/audio._Cfunc_initAudio: undefined: _cgo_e0a3be4f138e_Cfunc_initAudio

The result with MinGW:

It succeeded to compile and run, and while it didn't prevent the crash, at least it printed something out:

fatal error: unexpected signal during runtime execution
[signal 0xc0000005 code=0x1 addr=0x420f85 pc=0x42874c]

runtime stack:
invalid spdelta 96655 -1
runtime: unexpected return pc for _cgo_ec587e40eeca_Cfunc_initAudio called from
0x42874800
runtime.throw(0x455dc0)
        c:/go/src/pkg/runtime/panic.c:520 +0x71
runtime.sigpanic()
        c:/go/src/pkg/runtime/os_windows.c:352 +0x46
invalid spdelta 96655 -1
runtime: unexpected return pc for _cgo_ec587e40eeca_Cfunc_initAudio called from
0x42874800
_cgo_ec587e40eeca_Cfunc_initAudio()
        ?:0 +0xc

goroutine 16 [syscall]:
runtime.cgocall(0x428740, 0x533f64)
        c:/go/src/pkg/runtime/cgocall.c:143 +0xed fp=0x533f58 sp=0x533f2c
audiot/audio._Cfunc_initAudio(0x42e340)
        audiot/audio/_obj/_cgo_defun.c:53 +0x37 fp=0x533f64 sp=0x533f58
audiot/audio.Init(0x0, 0x0)
        C:/Users/Milan/Desktop/Dropbox/Projekty/Go/src/audiot/audio/at.go:23 +0x
3c fp=0x533f90 sp=0x533f64
main.main()
        c:/Users/Milan/Desktop/Dropbox/Projekty/Go/src/audiot/main.go:10 +0x29 f
p=0x533f9c sp=0x533f90
runtime.main()
        c:/go/src/pkg/runtime/proc.c:247 +0x11e fp=0x533fd0 sp=0x533f9c
runtime.goexit()
        c:/go/src/pkg/runtime/proc.c:1445 fp=0x533fd4 sp=0x533fd0
created by _rt0_go
        c:/go/src/pkg/runtime/asm_386.s:101 +0x102

goroutine 17 [syscall]:
runtime.goexit()
        c:/go/src/pkg/runtime/proc.c:1445
exit status 2

I also thought it can't hurt to post the specifics of my toolchain:

$ gcc --version
gcc.exe (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.

$ go version
go version go1.3 windows/386

And let's not forget Visual Studio 2013 Express

  • 写回答

2条回答 默认 最新

  • dongliulu1122 2014-08-20 16:54
    关注

    I just learnt Go 1.3.1 came out, so I tried updating... and the problem disappeared. (argh!)

    I guess it was a compiler bug then. Anyway, thanks to everyone who tried to help, I really appreciate it.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 csv格式数据集预处理及模型选择
  • ¥15 部分网页页面无法显示!
  • ¥15 怎样解决power bi 中设置管理聚合,详细信息表和详细信息列显示灰色,而不能选择相应的内容呢?
  • ¥15 QTOF MSE数据分析
  • ¥15 平板录音机录音问题解决
  • ¥15 请问维特智能的安卓APP在手机上存储传感器数据后,如何找到它的存储路径?
  • ¥15 (SQL语句|查询结果翻了4倍)
  • ¥15 Odoo17操作下面代码的模块时出现没有'读取'来访问
  • ¥50 .net core 并发调用接口问题
  • ¥15 网上各种方法试过了,pip还是无法使用