Skip to content

Panic at FD_SET #1401

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

Open
killme2008 opened this issue Jun 14, 2019 · 9 comments · Fixed by blackbeam/rust-mysql-simple#176
Open

Panic at FD_SET #1401

killme2008 opened this issue Jun 14, 2019 · 9 comments · Fixed by blackbeam/rust-mysql-simple#176
Labels
C-feature-request Category: new feature or request E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue.
Milestone

Comments

@killme2008
Copy link

killme2008 commented Jun 14, 2019

  • Platform: Linux dennis-thinkpad 4.15.0-39-generic Fix compile on DragonFly and FreeBSD #42-Ubuntu SMP Tue Oct 23 15:48:01 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
  • Info: When try to create more connections to a mysql server, panic at FD_SET.
  • Error:
panicked 'index out of bounds: the len is 16 but the index is 53' at 
"/root/.cargo/registry/src/mirrors.ustc.edu.cn-12df342d903acd47/libc-0.2.58/src/unix/notbsd/mod.rs:1177"
@killme2008
Copy link
Author

We don't use libc derectly, but use nix-0.11.0 such as

    let mut fd_set = select::FdSet::new();
    let socket_fd = fd;
    fd_set.insert(socket_fd);

Panic at fd_set.insert(socket_fd).

@gnzlbg
Copy link
Contributor

gnzlbg commented Jun 14, 2019

@killme2008 could you compile with --features=extra_traits, and dump fd_set and socket_fd before the insert call

    let mut fd_set = select::FdSet::new();
    let socket_fd = fd;
    dbg!(fd_set);
    dbg!(socket_fd);
    fd_set.insert(socket_fd);

?

cc @asomers

@asomers
Copy link
Contributor

asomers commented Jun 14, 2019

This is probably a bug in your application. select can only be used with file descriptors up to FD_SETSIZE.

@gnzlbg
Copy link
Contributor

gnzlbg commented Jun 14, 2019

@asomers does nix expose a "safe" wrapper over these APIs ?

@asomers
Copy link
Contributor

asomers commented Jun 14, 2019

No need. libc's exported FD_SET is already safe. That's why the application panic()ed rather than segfaulted.

@gnzlbg
Copy link
Contributor

gnzlbg commented Jun 14, 2019

Ok, then I'm going to leave this open here. While I agree with you that the bug is in user code, I think we should be providing a better error message in this situation, e.g., by asserting at the beginning of the function that the indices must be in bounds, and explaining what those bounds are, at least in debug mode via a debug_assert!.

@tgross35
Copy link
Contributor

For anyone looking to help, these functions

pub fn CMSG_FIRSTHDR(mhdr: *const msghdr) -> *mut cmsghdr {
if (*mhdr).msg_controllen as usize >= ::mem::size_of::<cmsghdr>() {
(*mhdr).msg_control as *mut cmsghdr
} else {
0 as *mut cmsghdr
}
}
pub fn CMSG_DATA(cmsg: *const cmsghdr) -> *mut ::c_uchar {
cmsg.offset(1) as *mut ::c_uchar
}
pub {const} fn CMSG_SPACE(length: ::c_uint) -> ::c_uint {
(CMSG_ALIGN(length as usize) + CMSG_ALIGN(::mem::size_of::<cmsghdr>()))
as ::c_uint
}
pub {const} fn CMSG_LEN(length: ::c_uint) -> ::c_uint {
CMSG_ALIGN(::mem::size_of::<cmsghdr>()) as ::c_uint + length
}
pub fn FD_CLR(fd: ::c_int, set: *mut fd_set) -> () {
let fd = fd as usize;
let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
(*set).fds_bits[fd / size] &= !(1 << (fd % size));
return
}
pub fn FD_ISSET(fd: ::c_int, set: *const fd_set) -> bool {
let fd = fd as usize;
let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
return ((*set).fds_bits[fd / size] & (1 << (fd % size))) != 0
}
pub fn FD_SET(fd: ::c_int, set: *mut fd_set) -> () {
let fd = fd as usize;
let size = ::mem::size_of_val(&(*set).fds_bits[0]) * 8;
(*set).fds_bits[fd / size] |= 1 << (fd % size);
return
}
pub fn FD_ZERO(set: *mut fd_set) -> () {
for slot in (*set).fds_bits.iter_mut() {
*slot = 0;
}
}
and maybe some others in that file should just use .get(...).unwrap_or_else(|| panic!(...)) rather than [...] indexing.

@tgross35 tgross35 added the E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. label Aug 29, 2024
@tgross35 tgross35 added this to the 1.x milestone Aug 29, 2024
@tgross35 tgross35 added the E-help-wanted Call for participation: Help is requested to fix this issue. label Nov 21, 2024
@highjeans
Copy link

Just for clarification, the functions prefixed with FD_ are for file descriptors? What about CMSG_?

@asomers
Copy link
Contributor

asomers commented Mar 18, 2025

Just for clarification, the functions prefixed with FD_ are for file descriptors? What about CMSG_?

The CMSG_ functions are not related. They are intended for use with sendmsg(2) and recvmsg(2), whereas the FD_ functions are for use with select(2).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-feature-request Category: new feature or request E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-help-wanted Call for participation: Help is requested to fix this issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants