-
Notifications
You must be signed in to change notification settings - Fork 13.4k
FFI to C segmentation fault (SIGSEGV: invalid memory reference) #65546
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
Comments
@parisholley are you able to obtain backtrace with |
I bet you corrupt your stack in "I have tried using both into_raw() and as_ptr() with the same results." prove you have no idea what you are doing. Also, it's very hard to follow you, you say if comment x line but not y line blabla, it's not a good way to describe a bug. |
tl;dr, after some sleep and a fresh look, it ended up being due to a NULL returned from the C library on the second invocation of @Stargateur I am aware of the distinction between the two in terms of mutability and that Nothing about your comment was respectful or helpful and I gave two ways to reproduce this problem all within about 30 seconds, so instead of "comment debugging" and assuming stupidity on the side of the contributor, actually have a productive conversation. I will re-iterate, if you comment out lines in the code I provided, that I have clearly linked to, I am giving you multiple ways to alter the occurrence of SIGSEGV (which I know why is happening now). Unless I am missing something, I would expect, given the NULL value returned from pub fn detect(&mut self, user_agent:&str){
let agent = CString::new(user_agent).expect("CString::new failed");
let agent_raw = agent.as_ptr();
unsafe {
let ws = fiftyoneDegreesProviderWorksetGet(&mut self.provider);
fiftyoneDegreesWorksetRelease(ws);
}
} pub fn detect(&mut self, user_agent:&str){
//let agent = CString::new(user_agent).expect("CString::new failed");
//let agent_raw = agent.as_ptr();
unsafe {
let ws = fiftyoneDegreesProviderWorksetGet(&mut self.provider);
fiftyoneDegreesWorksetRelease(ws);
}
} but in fact, the second one has 0 problems, which makes no sense, as nothing about agent/agent_raw is related to the code in the unsafe block. so understandably, when trying to debug this, I am being sent in the wrong direction and thinking it is RUST, and not the C library. I didn't have much lucking re-running the tests via GDB (or when reproducing the same logic in a bin), it appears to just hang after spawning the threads:
I will also note, i can reproduce this via test or bin, release or debug... |
the only other thing I can think of... is the FFI call, which fails due to the NULL pointer, is preventing rust from cleaning things up. as an example, if I decided to use pub fn detect(&mut self, user_agent:&str){
let agent = CString::new(user_agent).expect("CString::new failed");
let agent_raw = agent.into_raw();
forget(agent_raw); // not sure this helps this example, but i tried with it here and commented out
unsafe {
let cstring = CString::from_raw(agent_raw);
drop(agent_raw); // make sure that rust doesn't try to do something with this when FFI panics
let ws = fiftyoneDegreesProviderWorksetGet(&mut self.provider);
fiftyoneDegreesWorksetRelease(ws);
}
} but I still get the same error... so i'm not sure what about creating a Cstring ptr, allows the FFI call error to bubble up... but commenting it all out does not... |
another interesting thing I have found while trying to debug, when the FFI call at issue returns a null fiftyoneDegreesWorkset *ws = NULL;
if (pool->available > 0) {
// Worksets are available. Take one from the end of the array.
ws = pool->worksets[pool->available - 1];
pool->available--;
}
return ws; this implementation, has no SIGSEGV pub fn detect(&mut self, user_agent:&str){
unsafe {
let ws = fiftyoneDegreesProviderWorksetGet(&mut self.provider);
fiftyoneDegreesWorksetRelease(ws);
}
} if I alter the C library to put printf in for debugging purposes, it does SIGSEGV: fiftyoneDegreesWorkset *ws = NULL;
if (pool->available > 0) {
// Worksets are available. Take one from the end of the array.
ws = pool->worksets[pool->available - 1];
pool->available--;
printf("available");
}
printf("unavailable");
return ws; |
Like in #65567, you move the |
@parisholley pardon my rudeness, I sux in english so I take shortcut when I'm writing, you should not be offended because I said you have no idea what you are doing, for example, ask me to code in javascript, I will have no idea of what I'm doing. I said that because you seem so sure of you in your issue. Whereas you should have been very suspicious of your code. That a classic beginner mistake to feel they understand everything. |
Uh oh!
There was an error while loading. Please reload this page.
creating a new issue since #59202 is closed, but may be related.
you can check out a fork of a c library I am trying to build a wrapper for. and this error is strange, because i commented out all of my C calls that pass the CString as an arg, so i'm not even sending it anywhere, and can get it to segfault repeatedly.
On Mac:
On Ubuntu:
a few things are interesting though, notice these two lines:
https://github.com/parisholley/Device-Detection/blob/7d04b4a99526bff53e35843c9a2347a4b955d110/rust/pattern.rs#L127-L132
If i comment out line 131, and only call the
detect
function once, there is no problem. it is only when called a second time, thatSIGSEGV
is thrown. I have tried using bothinto_raw()
andas_ptr()
with the same results.what makes this EVEN more strange, is if in that same function, i comment out 78 and 111, so that only 74/75 (CString) is live, no segfault. if i do the opposite, and comment out 74/75, but leave 78/111 live, no segfault. it is only when the two, seemingly unrelated calls are in the same function, that things go crazy.
my environment:
i'll try to work on creating a smaller reproduce case
The text was updated successfully, but these errors were encountered: