Im使用枚举上的untagged属性来序列化和反序列化JSON。
// Just an example of using `untagged` - not actual code with the issue.
#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum Message {
String(String),
X(X),
}我在运行时为我的一些类型获得了一个fatal runtime error: stack overflow。
通过使用Box,这些类型可能具有递归定义。
通常,在使用untagged属性时,什么会导致堆栈溢出?
文档没有说明任何限制,因此似乎它应该适用于任何编译的代码。
这是我在Mac上用仪器/采样器收集到的堆栈跟踪,__rust_probestack似乎是最后一个调用的函数,此时它大约有70个函数深。

发布于 2020-12-16 20:46:13
https://github.com/serde-rs/serde/issues/1062#issuecomment-335659227
通过将堆栈设置为16 to来修正:
export RUST_MIN_STACK=16777216 && cargo test
发布于 2020-12-16 13:40:56
根据您在注释中所说的内容,您有递归类型。问题来自于untagged的工作方式。下面是一个重现问题的最小示例:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum Foo {
Foo(Box<Foo>),
Bar(String),
}
fn main() {
let data = r#""Bar""#;
let _v: Foo = serde_json::from_str(&data).unwrap();
}问题是,使用untagged时,Serde试图将数据解析为枚举的第一个变体,然后如果失败了,则返回并尝试第二个变体,依此类推。下面是上面这个例子的结果:
Foo的值,该值是无标记的,因此Serde试图解析一个与第一个变量匹配的值。Box<Foo>,所以Serde试图解析一个Foo类型的值,该值是无标记的,所以Serde试图解析一个与第一个变量匹配的值。Box<Foo>,所以Serde试图解析一个Foo类型的值,该值是无标记的,所以Serde试图解析一个与第一个变量匹配的值。注意,这与输入数据无关,这段代码甚至在尝试读取单个字节的数据之前都会失败!
为了避免这个问题,您必须确保Serde在递归之前总是使用一些数据,例如:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
#[serde(untagged)]
enum Foo {
Foo(String, Box<Foo>),
Bar(String),
}
fn main() {
let data = r#""Bar""#;
let _v: Foo = serde_json::from_str(&data).unwrap();
}https://stackoverflow.com/questions/65309013
复制相似问题