Skip to content

Panic at FD_SET #1401

Open
blackbeam/rust-mysql-simple
#176
@killme2008

Description

@killme2008
  • 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"

Activity

killme2008

killme2008 commented on Jun 14, 2019

@killme2008
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

gnzlbg commented on Jun 14, 2019

@gnzlbg
Contributor

@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

asomers commented on Jun 14, 2019

@asomers
Contributor

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

gnzlbg

gnzlbg commented on Jun 14, 2019

@gnzlbg
Contributor

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

asomers

asomers commented on Jun 14, 2019

@asomers
Contributor

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

gnzlbg

gnzlbg commented on Jun 14, 2019

@gnzlbg
Contributor

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

tgross35 commented on Aug 29, 2024

@tgross35
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.

added
E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
on Aug 29, 2024
added this to the 1.x milestone on Aug 29, 2024
added
E-help-wantedCall for participation: Help is requested to fix this issue.
on Nov 21, 2024
highjeans

highjeans commented on Mar 18, 2025

@highjeans

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

asomers

asomers commented on Mar 18, 2025

@asomers
Contributor

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-feature-requestCategory: new feature or requestE-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.E-help-wantedCall for participation: Help is requested to fix this issue.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

      Participants

      @killme2008@asomers@gnzlbg@tgross35@highjeans

      Issue actions

        Panic at FD_SET · Issue #1401 · rust-lang/libc