You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在嵌套Rc<RefCell>的结构体中使用GDB美化打印机?

解决Rust中嵌套Rc<RefCell<FileSystemNode>>的GDB美化打印机失效问题

我定义了如下FileSystemNode结构体,通过嵌套Rc<RefCell<FileSystemNode>>实现节点与父子节点间的可变和不可变访问:

struct FileSystemNode{
    current_directory_path: String,
    current_directory_name: String,
    // 需要对节点进行可变和不可变访问
    // (从当前节点到子节点,或从子节点的子节点到父节点)
    parent_directory: Option<Rc<RefCell<FileSystemNode>>>,
    children: Vec<Rc<RefCell<FileSystemNode>>>,
    // size为0时表示这是一个目录
    size: usize
}

但用GDB打印该结构体时,会递归遍历所有父子节点,陷入死循环。为解决这个问题,我编写了如下GDB美化打印机:

class FileSystemNodePrinter:
    def __init__(self, val):
        self.val = val
    
    def to_string(self):
        return 'test'
        
    def display_hint(self):
        return 'FileSystemNode'

该打印机已在info pretty-printer中显示注册成功,但实际打印时未生效,输出和未使用美化打印机时一致:

$1 = Rc(strong=1, weak=0) = {value = RefCell(borrow=0) = {
    value = advent_of_code_2022::day7::FileSystemNode {
    current_directory_path: "/",
    current_directory_name: "", 
    parent_directory: core::option::Option<alloc::rc::Rc<core::cell::RefCell<advent_of_code_2022::day7::FileSystemNode>>>::none, 
    children: Vec(size=0), 
    size: 0},
    borrow = 0},
    strong = 1, weak = 0}

我推测问题出在FileSystemNode被嵌套在Rc<RefCell>中,现寻求解决方法。以下是完整复现代码及配置:

复现步骤

Rust完整代码

use std::cell::RefCell;
use std::rc::Rc;

struct FileSystemNode{
    current_directory_path: String,
    current_directory_name: String,
    // 需要对节点进行可变和不可变访问
    // (从当前节点到子节点,或从子节点的子节点到父节点)
    parent_directory: Option<Rc<RefCell<FileSystemNode>>>,
    children: Vec<Rc<RefCell<FileSystemNode>>>,
    // size为0时表示这是一个目录
    size: usize
}

impl FileSystemNode {
    pub fn new() -> FileSystemNode {
        return FileSystemNode {
            current_directory_path: String::from(""),
            current_directory_name: String::from(""),
            parent_directory: None,
            children: Vec::new(),
            size: 0
        };
    }
}

pub fn main(){
    let root = Rc::new(RefCell::new(FileSystemNode::new()));
    root.borrow_mut().current_directory_path = String::from("/");

    let node = Rc::new(RefCell::new(FileSystemNode::new()));
    node.borrow_mut().current_directory_path = String::from("/test/");
    node.borrow_mut().current_directory_name = String::from("test");
    node.borrow_mut().parent_directory = Some(Rc::clone(&root));

    root.borrow_mut().children.push(Rc::clone(&node));

    println!("");
}

.gdbinit配置

import sys

sys.path.insert(0, "/path/to/FileSystemNodePrettyPrinterParent")

from FileSystemNodePrettyPrinter import register_printer
register_printer(None)

end

layout next

完整FileSystemPrettyPrinter.py代码

# 临时简易美化打印机,用于解决无限递归问题

import gdb

class FileSystemNodePrinter:
    def __init__(self, val):
        self.val = val
    
    def to_string(self):
        return 'test'
        
    def display_hint(self):
        return 'FileSystemNode'
        
        
        
def register_printer(objfile):
    if objfile == None:
        objfile = gdb.current_objfile()
    gdb.printing.register_pretty_printer(objfile, build_pretty_printer(), True)
    print("Registered pretty printers for UE classes")
    
def build_pretty_printer():
    pp = gdb.printing.RegexpCollectionPrettyPrinter("Custom")
    pp.add_printer("FileSystemNode", '^FileSystemNode$', FileSystemNodePrinter)
    return pp
    
register_printer(None)

配置好.gdbinit中的路径后启动程序,在root初始化完成后执行打印操作即可复现问题。

内容的提问来源于stack exchange,提问作者Tare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 07:17:11