Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alsa Lib segfaults when built statically #349

Closed
cybersoulK opened this issue Sep 4, 2023 · 11 comments
Closed

Alsa Lib segfaults when built statically #349

cybersoulK opened this issue Sep 4, 2023 · 11 comments

Comments

@cybersoulK
Copy link

cybersoulK commented Sep 4, 2023

I am building a game that uses alsa. All of my linux players segfault. This has been going for over 1 year.
Alsa-lib is built statically on a ubuntu machine with the following commands:

git clone https://github.com/alsa-project/alsa-lib
cd alsa-lib

apt-get update
apt-get install libtool
apt-get install make
apt install autoconf

autoreconf -i
./configure --disable-shared
make

Then i use libasound.a to build my Rust executable (On my mac machine).

I do the same process to build openssl for linux and it works great.

So There definitely is an issue when building alsa lib statically.

One of my players was able to provide me with a core dump that might be helpful to track down the fault:

image

coredump.txt

@perexg
Copy link
Member

perexg commented Sep 4, 2023

Follow INSTALL (https://github.com/alsa-project/alsa-lib/blob/master/INSTALL):

Compilation of static library
-----------------------------

If you would like to use the static ALSA library, you need to use these
options for the configure script:

        ./configure --enable-shared=no --enable-static=yes

Unfortunately, due to bug in the libtool script, the shared and static
library cannot be built together.

@perexg perexg closed this as completed Sep 4, 2023
@perexg
Copy link
Member

perexg commented Sep 4, 2023

A little bit further analysis:

The --disable-shared and --enable-shared=no --enable-static=yes seems identical (at least it works with the current autoconf/libtool).

But... The crash is in dlinfo call from libc. See the config.log (grep dlopen config.log):

checking whether a statically linked program can dlopen itself
configure:12995: warning: Using 'dlopen' in statically linked applications requires at runtime
the shared libraries from the glibc version used for linking

Use --without-libdl to avoid use of the dynamic symbols (and external plugins) outside alsa-lib for the configure script.

@cybersoulK
Copy link
Author

cybersoulK commented Sep 5, 2023

@perexg

The executable is still segfaulting.

i ran the updated commands:

git clone https://github.com/alsa-project/alsa-lib
cd alsa-lib

apt-get update
apt-get install libtool
apt-get install make
apt install autoconf

autoreconf -i
./configure --enable-shared=no --enable-static=yes --without-libdl
make

i use the
alsa-lib/src/.libs/libasound.a
alsa-lib/include/*

i moved them to a new include and lib folder, and made sure the .pc points to them:
this is the .pc file:

prefix=/Users/my_name/Desktop/alsa
libdir=${prefix}/lib
includedir=${prefix}/include

Name: alsa
Description: Advanced Linux Sound Architecture (ALSA) - Library
Version: 1.2.10
Requires: 
Libs: -L${libdir} -lasound
Libs.private: -lm -lpthread -lrt
Cflags: -I${includedir}

It compiles/links successfully in rust (x86_64-unknown-linux-gnu) both using:
https://github.com/rust-cross/cargo-zigbuild (glibc version 2.38)
and
https://github.com/messense/homebrew-macos-cross-toolchains (glibc version 2.17)

Is there anything that i am doing wrong?

My player tester was not able to provide me with a core dump. and as of now virtualbox.org is down, i would try but i am also not a skilled linux user.

Can you try it out directly at https://cybergate.app so that we can track the issue quicker?
Press the download and finish the launcher download process. A folder named client and its executable that contains alsa will be generated. move the file to the main cybergate folder and test it there.

@perexg
Copy link
Member

perexg commented Sep 5, 2023

Provide a straight small binary which shows the issue. Also, you may compile your code with debugging symbols and use gdb debugger to get the full back trace (bt command when program crashes in gdb).

@perexg perexg reopened this Sep 5, 2023
@cybersoulK
Copy link
Author

cybersoulK commented Sep 5, 2023

rodio_test.zip

This should be a MVP to repro the issue.
The prints should probably indicate where the executable crashes.

use std::{io::BufReader, thread::sleep, time::Duration};

fn main() {

    println!("starting");

    std::panic::set_hook(Box::new(|panic_info| { 
        use std::io::Write;
        
        let mut file = std::fs::File::create("./error").unwrap();
        file.write_all(panic_info.to_string().as_bytes()).unwrap();

        println!("{}", panic_info.to_string());
    }));

    println!("starting2");

    let (_stream, stream_handle) = rodio::OutputStream::try_default().unwrap();

    println!("OutputStream");

    let file = std::fs::File::open("./sound.wav").unwrap();
    
    let sink = stream_handle.play_once(BufReader::new(file)).unwrap();

    println!("played");
        
    sink.set_volume(0.5);

    while sink.empty() == false {}

    println!("is empty");

    sleep(Duration::from_secs_f32(4.0));

    println!("exit");
}

@perexg
Copy link
Member

perexg commented Sep 5, 2023

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7d2adea in __GI_getenv (name=name@entry=0x5555555a0ecb "ALSA_CONFIG_PATH") at getenv.c:51
51            for (ep = __environ; *ep != NULL; ++ep)                                                                                                           
(gdb) bt
#0  0x00007ffff7d2adea in __GI_getenv (name=name@entry=0x5555555a0ecb "ALSA_CONFIG_PATH") at getenv.c:51
#1  0x00005555557bdc14 in snd_config_update_r (_top=_top@entry=0x555555843700 <snd_config>, _update=_update@entry=0x555555843748 <snd_config_global_update>, 
    cfgs=cfgs@entry=0x0) at conf.c:4529
#2  0x00005555557be02e in snd_config_update_ref (top=top@entry=0x7fffffffca20) at conf.c:4703
#3  0x00005555557ce2fb in snd_pcm_open (pcmp=0x7fffffffca98, name=0x7ffff7be7ac0 "default", stream=SND_PCM_STREAM_PLAYBACK, mode=1) at pcm.c:2709
#4  0x000055555575e565 in alsa::pcm::PCM::open (name=..., dir=alsa::Direction::Playback, nonblock=true) at src/pcm.rs:131
#5  0x000055555575e44a in alsa::pcm::PCM::new (name=..., dir=alsa::Direction::Playback, nonblock=true) at src/pcm.rs:120
#6  0x000055555573c084 in cpal::host::alsa::DeviceHandles::try_open (self=0x7fffffffdb20, name=..., stream_type=alsa::Direction::Playback)
    at src/host/alsa/mod.rs:203
#7  0x000055555573c210 in cpal::host::alsa::DeviceHandles::get_mut (self=0x7fffffffdb20, name=..., stream_type=alsa::Direction::Playback)
    at src/host/alsa/mod.rs:216
#8  0x000055555573cff3 in cpal::host::alsa::Device::supported_configs (self=0x7fffffffdb00, stream_t=alsa::Direction::Playback) at src/host/alsa/mod.rs:297
#9  0x000055555573e59f in cpal::host::alsa::Device::default_config (self=0x7fffffffdb00, stream_t=alsa::Direction::Playback) at src/host/alsa/mod.rs:449
#10 0x000055555573ea03 in cpal::host::alsa::Device::default_output_config (self=0x7fffffffdb00) at src/host/alsa/mod.rs:487
#11 0x000055555573bb46 in cpal::host::alsa::{impl#2}::default_output_config (self=0x7fffffffdb00) at src/host/alsa/mod.rs:86
#12 0x00005555557453bb in cpal::platform::platform_impl::{impl#5}::default_output_config (self=0x7fffffffdb00) at src/platform/mod.rs:253
#13 0x000055555568de25 in rodio::stream::{impl#11}::try_new_output_stream (self=0x7fffffffdb00) at src/stream.rs:236
#14 0x00005555556791c7 in rodio::stream::OutputStream::try_from_device (device=0x7fffffffdb00) at src/stream.rs:31
#15 0x0000555555679638 in rodio::stream::OutputStream::try_default () at src/stream.rs:48
#16 0x000055555562f4cc in rodio_test::main () at src/main.rs:19
#17 0x0000555555632a1b in core::ops::function::FnOnce::call_once<fn(), ()> ()
    at /rustc/33a2c2487ac5d9927830ea4c1844335c6b9f77db/library/core/src/ops/function.rs:250
#18 0x00005555556442ee in std::sys_common::backtrace::__rust_begin_short_backtrace<fn(), ()> (f=0x55555562f400 <rodio_test::main>)
--Type <RET> for more, q to quit, c to continue without paging--
    at /rustc/33a2c2487ac5d9927830ea4c1844335c6b9f77db/library/std/src/sys_common/backtrace.rs:135
#19 0x000055555566e711 in std::rt::lang_start::{closure#0}<()> () at /rustc/33a2c2487ac5d9927830ea4c1844335c6b9f77db/library/std/src/rt.rs:166
#20 0x000055555578287b in core::ops::function::impls::{impl#2}::call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> () at library/core/src/ops/function.rs:284
#21 std::panicking::try::do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> ()
    at library/std/src/panicking.rs:500
#22 std::panicking::try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> ()
    at library/std/src/panicking.rs:464
#23 std::panic::catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> ()
    at library/std/src/panic.rs:142
#24 std::rt::lang_start_internal::{closure#2} () at library/std/src/rt.rs:148
#25 std::panicking::try::do_call<std::rt::lang_start_internal::{closure_env#2}, isize> () at library/std/src/panicking.rs:500
#26 std::panicking::try<isize, std::rt::lang_start_internal::{closure_env#2}> () at library/std/src/panicking.rs:464
#27 std::panic::catch_unwind<std::rt::lang_start_internal::{closure_env#2}, isize> () at library/std/src/panic.rs:142
#28 std::rt::lang_start_internal () at library/std/src/rt.rs:148
#29 0x000055555566e6ea in std::rt::lang_start<()> (main=0x55555562f400 <rodio_test::main>, argc=1, argv=0x7fffffffe378, sigpipe=0)
    at /rustc/33a2c2487ac5d9927830ea4c1844335c6b9f77db/library/std/src/rt.rs:165
#30 0x000055555562f7ce in main ()
#31 0x00007ffff7d11b4a in __libc_start_call_main (main=main@entry=0x55555562f7b0 <main>, argc=argc@entry=1, argv=argv@entry=0x7fffffffe378)
    at ../sysdeps/nptl/libc_start_call_main.h:58
#32 0x00007ffff7d11c0b in __libc_start_main_impl (main=0x55555562f7b0 <main>, argc=1, argv=0x7fffffffe378, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe368) at ../csu/libc-start.c:360
#33 0x000055555560f0d1 in _start ()

So it crashes in the standard libc code (getenv).

Your program uses system's glibc:

$ ldd ./rodio_test 
	linux-vdso.so.1 (0x00007ffd651fe000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f4eacb1f000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4eacf79000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f4eac941000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f4eacf94000)

It seems that your statically linked parts are incompatible with distro specific glibc. Try to compile whole executable as static.

@perexg
Copy link
Member

perexg commented Sep 5, 2023

Or you just overwrite memory and those crashes are just a side-effect of a bad code.

@cybersoulK
Copy link
Author

cybersoulK commented Sep 5, 2023

why would this be? And why does it Compile and Links successfuly?
It seems that your statically linked parts are incompatible with distro specific glibc. Try to compile whole executable as static.

I used two different crates, kira and rodio. both segfault. It could be the cpal and the alsa-sys crate (dependencies that they both use), but they work when compiling from linux to linux. (but that doesn't need the manual building alsa-lib).

The problem that i am having is when compiling from mac to linux with the static library.

Rust code is usually pretty robust with memory, but we can open this issue on the rust alsa-sys

@cybersoulK
Copy link
Author

cybersoulK commented Sep 5, 2023

so, the ubuntu machine that i build the static alsa-lib has version:
ldd (Ubuntu GLIBC 2.36-0ubuntu4) 2.36

I build the executable with 2.36 using cargo-zigbuild.

rodio_test (matches glibc).zip

see if we can get this one to work.

could the toolchain be the fault?
https://github.com/rust-cross/cargo-zigbuild

where is says "Known upstream zig issues"?

@MIvanchev
Copy link

Maybe try a very simple C build to isolate whether alsa is really the issue before doing complex integrated builds.

@cybersoulK
Copy link
Author

cybersoulK commented May 20, 2024

since then, i used cargo cross, to successfully compile Alsa on a arm mac to x86 linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants