Skip to content

Meeting a terrible fate when calling debug! macro from C #17559

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

Closed
martinraison opened this issue Sep 26, 2014 · 4 comments
Closed

Meeting a terrible fate when calling debug! macro from C #17559

martinraison opened this issue Sep 26, 2014 · 4 comments

Comments

@martinraison
Copy link

I have a C program using a rust library that calls the debug! macro. Here is the setup:

system: OS X Mavericks 10.9.4

bar.rs

#![feature(phase)]

#[phase(plugin, link)]
extern crate log;

#[no_mangle]
pub unsafe extern "C" fn test() {
    debug!("Hello");
}

bar.h

void test();

test.c

#include "bar.h"

int main(int argc, char *argv[]) {
    test();
}

I'm able to compile it using

rustc --crate-type staticlib bar.rs
gcc -Wall -o test test.c -L. -lbar

but it crashes at runtime:

$ ./test

You've met with a terrible fate, haven't you?

fatal runtime error:  assertion failed: queue != 0
[1]    42775 illegal hardware instruction  ./test

I don't think the problem is specific to the debug! macro, because I've seen the exact same error in other situations. However this is the simplest example I've found. Note that I've been able to run other C programs using Rust libraries successfully (for example if I replace debug! with println! in the example, then everything is fine).

Maybe I'm missing a step somewhere, but it looks like a bug to me.

@martinraison
Copy link
Author

Investigating a bit more, it looks like the assertion queue != 0 fails in at_exit_impl.rs because the queue has not been initialized. So I solved my problem by manually initializing the runtime:

std::rt::init(0, std::ptr::null());

Of course it makes sense now, but is this is the recommended way to do it? It also means many rust libraries will require some kind of init() function to be called (which is fine, I guess).

@kmcallister
Copy link
Contributor

As I see it, the solution is to compile with #![no_std] and provide your own begin_unwind.

@martinraison
Copy link
Author

I see - thanks for your reply! I tried using #![no_std] originally but my project is using things like ChanReader which don't seem to be available outside of std.

@thestinger
Copy link
Contributor

You need to use #![no_std] if you want to provide a Rust library with a normal C API. You're running into explicitly undefined behaviour if you aren't initializing the runtime on every thread before using libstd.

lnicola pushed a commit to lnicola/rust that referenced this issue Jul 28, 2024
Encode ident rawness and literal kind separately in tt::Leaf
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