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

The value of SIGCHLD is changed through binding in Linux docker container on MacOS #2979

Open
sshwy opened this issue Nov 14, 2024 · 5 comments

Comments

@sshwy
Copy link

sshwy commented Nov 14, 2024

Scenario: I'm currently developing my application in a docker container on MacOS. I wish to use kill and other related apis in Rust. Therefore I need to port those signal constants from C header to Rust. However I found that the value of SIGCHLD, which should be 17, is changed to 20.

The bindgen version is 0.65.1.

About the container (generate by Docker Desktop's dev container):

$ uname -a
Linux 64b26c15efbc 6.10.4-linuxkit #1 SMP Mon Aug 12 08:47:01 UTC 2024 aarch64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 11 (bullseye)
Release:        11
Codename:       bullseye

Here's a mininal error reproduction (repo):

// main.rs
mod testit {
    #![allow(non_upper_case_globals)]
    #![allow(non_camel_case_types)]
    #![allow(non_snake_case)]
    #![allow(unused)]

    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}

fn main() {
    println!("Hello, world!");
    println!(
        "SIGCHLD = {}, but get_sigchld returns {}",
        testit::SIGCHLD,
        unsafe { testit::get_sigchld() }
    );
}
// testit.h
#include <unistd.h>
#include <signal.h>

#ifndef MY_LIB_H
#define MY_LIB_H

int get_sigchld();

#endif
// testit.c
#include "testit.h"

int get_sigchld() { return SIGCHLD; }

Performing cargo run gives the following output:

SIGCHLD = 20, but get_sigchld returns 17
@pvdrz
Copy link
Contributor

pvdrz commented Nov 14, 2024

my best bet is that bindgen is being fed different system headers than the C compiler you're using to compile testit.c.

I cannot reproduce it on my system:

$ cat input.h
#include <unistd.h>
#include <signal.h>

#ifndef MY_LIB_H
#define MY_LIB_H

int get_sigchld();

#endif
$ bindgen input.h | grep "SIGCHLD"
pub const SIGCHLD: u32 = 17;
$ bindgen --version
bindgen 0.65.1

If I clone and cargo run your repo, I get:

     Running `target/debug/test_bindgen`
Hello, world!
SIGCHLD = 17, but get_sigchld returns 17

@sshwy
Copy link
Author

sshwy commented Nov 24, 2024

my best bet is that bindgen is being fed different system headers than the C compiler you're using to compile testit.c.

I cannot reproduce it on my system:

$ cat input.h
#include <unistd.h>
#include <signal.h>

#ifndef MY_LIB_H
#define MY_LIB_H

int get_sigchld();

#endif
$ bindgen input.h | grep "SIGCHLD"
pub const SIGCHLD: u32 = 17;
$ bindgen --version
bindgen 0.65.1
If I clone and cargo run your repo, I get:

     Running `target/debug/test_bindgen`
Hello, world!
SIGCHLD = 17, but get_sigchld returns 17

Actually I found that 20 is the value of SIGCHLD on MacOS. But AFAIK, applications running in Docker container are not able to access header files on the host OS directly (unless some mappings are setup on purpose). So I'm really confused.

@pvdrz
Copy link
Contributor

pvdrz commented Nov 25, 2024

There are libraries that already let you do signal handling in a portable manner so you don't have to deal with such issues. If you want the same API exposed by signal.h you could use libc. If you want higher level abstractions you may use signal_hook

@sshwy
Copy link
Author

sshwy commented Jan 5, 2025

There are libraries that already let you do signal handling in a portable manner so you don't have to deal with such issues. If you want the same API exposed by signal.h you could use libc. If you want higher level abstractions you may use signal_hook

Sorry for the late reply and thank you for your advice! I'll use these API instead. But still I spent some debugging it, and I think I've found the bug. It seems that bindgen cannot handle #undef properly (#2722). In my situation, the SIGCHLD is first defined in /usr/include/aarch64-linux-gnu/bits/signum-generic.h by

#define	SIGCHLD		20

then redefined in /usr/include/aarch64-linux-gnu/bits/signum.h by

#undef	SIGCHLD
#define	SIGCHLD		17

And bindgen takes the first definition into account.

@ojeda
Copy link
Contributor

ojeda commented Jan 5, 2025

Looks like a duplicate of that one then -- thanks for getting to the bottom of it!

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