related code main.rs
fn main() {
println!("{:?}",mimey::binary_search("zsh"));
}
lib.rs
// MIME is a [(&str, &str); 670]
fn strcmp(x: &[u8], z: &[u8]) -> isize {
if x.is_empty() || z.is_empty() {
return 0;
}
if x[0] != z[0] {
// clamp (dont want to skip an index now do i)
return ((x[0] as isize) - z[0] as isize).clamp(-1, 1);
}
strcmp(&x[1..], &z[1..])
}
// it segfaults. somehow
fn bins(k: &[u8], ci: usize) -> Option<&str> {
let sp = strcmp(k, MIME[ci].0.as_bytes());
if sp == 0 {
return Some(MIME[ci].1);
}
if ci == 0 || ci == MIME.len() - 1 {
return None;
}
bins(k, ci.checked_add_signed(sp)?)
}
pub fn binary_search(k: &str) -> Option<&str> {
bins(k.as_bytes(), MIME.len() / 2)
}
uname:
Linux r0 6.9.1-0-edge #1-Alpine SMP PREEMPT_DYNAMIC
rustc -vV:
rustc 1.78.0 (9b00956e5 2024-04-29) (Alpine Linux 1.78.0-r0)
binary: rustc
commit-hash: 9b00956e56009bab2aa15d7bff10916599e3d6d6
commit-date: 2024-04-29
host: x86_64-alpine-linux-musl
release: 1.78.0
LLVM version: 17.0.6
lldb:
* thread #1, name = 'mimey', stop reason = signal SIGSEGV: address not mapped to object (fault address: 0x7fffff7fe9a8)
frame #0: 0x0000555555563d01 mimey`mimey::bins::hee7c9bb096833bc5(k=(data_ptr = "", length = 1), ci=1) at lib.rs:706
703 }
704
705 // it segfaults. somehow
-> 706 fn bins(k: &[u8], ci: usize) -> Option<&str> {
707 let sp = strcmp(k, MIME[ci].0.as_bytes());
708 if sp == 0 {
709 return Some(MIME[ci].1);
MIME
is defined in lib.rs
. I don't have any idea why k
seems to be empty.
This is part of a mime-guessing library I've been writing for fun..
Not enough information to be 100%, but there appears to be a logical error in your code that can result in an infinite loop, which would overflow the stack and then SIGSEGV.
Imagine Mime is defined as so:
const MIME: [(&'static str, &'static str); 4] =
[("000", "?"), ("002", "?"), ("006", "?"), ("007", "?")];
then, binary_search("005")
will never exit, overflow the stack, and throw SIGSEGV. Specifically, you enter a state where bins(k, 2)
calls bins(k, 3)
, which calls bins(k, 2)
.
Without knowing the exact values of MIME it's impossible to be sure, but I suspect this is what is happening. Add a line printing sp
before your sp == 0
check, and you should see alternating 1, and -1 values.