Skip to content
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

instrument macro causes Infinite recursion #3209

Open
MrFoxPro opened this issue Feb 4, 2025 · 1 comment
Open

instrument macro causes Infinite recursion #3209

MrFoxPro opened this issue Feb 4, 2025 · 1 comment

Comments

@MrFoxPro
Copy link

MrFoxPro commented Feb 4, 2025

Bug Report

Version

0.1.41, also tried 0.1.3*

Platform

Linux 6.12 x64, rust nightly

Description

I used tracing with macros in multiple pretty big projects sucessfully, but didn't encounter such problem.

thread 'tokio-runtime-worker' has overflowed its stack
fatal runtime error: stack overflow

I spent few hours looking for cause and found that this happens because of annotating one of methods with insturment macro.

But something really weird is going on.
I have very simple logic

// message_handler
tracing::debug!("command name: {}", cmd.name);
match cmd.name.as_str() {
    "/reply" if is_admin => {
        let command_context = cmd::CommandContext { chat_id, msg, cmd, user, is_admin };
        return cmd::reply(command_context, ctx).await
    }
...
// cmd::reply
#[tracing::instrument(err, skip_all)]
pub async fn reply(CommandContext { msg, ..}: CommandContext, ctx: AppContext) -> AppResult<()> {
	let text = msg.get_text()
		.map(|x| x.data.clone())
		.unwrap_or(String::new()).replace("/reply ", "");

	let space_idx = text.find(" ")
		.ok_or(anyhow::anyhow!("text was not found"))?;

	let chat_id = text[0..space_idx].to_string();
	let text = text[(space_idx + 1)..].trim().to_string();

	SendMessage::new(chat_id.clone(), text).parse_mode("markdown")
		.exec(&ctx.bot).await?;

	SetMessageReaction::new(msg.chat.id, msg.message_id)
		.reaction([ReactionType::Emoji(ReactionTypeEmoji::new("👍", "emoji"))])
		.exec(&ctx.bot).await?;

	Ok(())
}

stack overflow happens if there is external function call in match. But when running, program doesn't even get to the match statement and does not output "command name" debug before crashing.
Replacing return cmd::reply(command_context, ctx).await with return Ok(()) fixes crash.
Seems like instrument macro breaks code flow.

What i tried:

  • multiple rustc versions, from 1.81
  • previous versions of tracing and tracing-subscriber
  • multiple previous versions of tokio

It didn't help. I replaced tracing with fastrace + logforth + logcalls crates (they provide similiar features and macros) and there was no this issue too.

I ran cargo expand with and without instrument macro on problematic method macro:
expand_bad.rs.txt
expand_ok.rs.txt
(look for handle_update, message_handler, cmd::reply calls)

@MrFoxPro MrFoxPro changed the title Using instrument macro causes Infinite recursion instrument macro causes Infinite recursion Feb 4, 2025
@MrFoxPro
Copy link
Author

MrFoxPro commented Feb 4, 2025

my hypotheses of probable cause:

  • .exec uses reqwest + multipart inside, there is issue with it
  • I'm using local dependency in Cargo.toml which contains large auto-generated .rs file, maybe it is somehow related to generics expansion for a large number of types and/or incorrect dependency resolution
  • Using new async traits in local dependency

probably related: #3197

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant