Tokio-runtime-worker Stack overflow

While I knew it was theoretically possibly, I hadn't anticipated running into one. I'm receiving the following:

thread 'tokio-runtime-worker' has overflowed its stack
fatal runtime error: stack overflow
sh: line 1: 90747 Abort trap: 6           cargo run --bin mtbox-warp-admin
[Finished running. Exit status: 134]

And I have no idea how to proceed. Suggestions?

Seems to happen within the following code:


            let kinds: Vec<String> = kinds
                .iter()
                .map(|kind| kind.to_string().to_lowercase())
                .collect();

Even when I re-write the code as follows I receive the stack overflow (note, the END, print does not output):

            println!("KINDS TO STRING - START");
            let mut kind_params = Vec::new();

            for kind in kinds.iter() {
                kind_params.push(kind.to_string().to_lowercase())
            }

            println!("KINDS TO STRING - END");

Seems that the to_string() implementation of my kinds type is to blame...

            println!("KINDS TO STRING - START");
            let mut kind_params = Vec::new();

            for kind in kinds.iter() {
                println!("KINDS TO STRING");
                let kind = kind.to_string();

                println!("KINDS TO LOWERCASE");
                let kind = kind.to_lowercase();
                println!("KINDS PUSH ");
                kind_params.push(kind);
            }
            println!("KINDS TO STRING - END");

The overflow happens in the kind.to_string() call, at least I'm assuming so because I'm not getting the "KINDS TO LOWERCASE" output.

The following is my Display implementation for my Slug type which is being processed under the kind variable name.

impl Display for Slug {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self)
    }
}

lols...

impl Display for Slug {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self)
    }
}

Seems that I'm just not smart. Calling write! on self tries to recursively call fmt in a recursive loop forever. :man_facepalming:

2 Likes

Changed my Display implementation for Slug to something like the following:

impl Display for Slug {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::VariantOne => write!(f, "{}", "VARIANT_ONE"),
            Self::VariantTwo => write!(f, "{}", "VARIANT_TWO"),
            Self::VariantThree => write!(f, "{}", "VARIANT_THREE"),
            Self::VariantFour => write!(f, "{}", "VARIANT_FOUR"),
            Self::Unknown(string) => write!(f, "UNKNOWN({})", string),
        }
    }
}

I feel like there is a better way to do this, but it's midnight and it works for now. Hopefully this thread will be helpful to someone in the future, infinite loops can still overflow the stack, who knew?! :smile_cat:

Well, it's not an infinite loop, it's a real recursive call, since write! expands to code which calls fmt.

infinite recursion then, depends on how you would like to define it. I believe that both can be implemented via goto :stuck_out_tongue_winking_eye:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.