Reflection via DWARF.

Related tags

Command-line deflect
Overview

deflect

[EXPERIMENTAL] Deflect brings reflection to Rust using DWARF debug info.

Deflect can be used to recover the concrete types of trait objects, inspect the internal state of async generators, and pretty-print arbitrary data.

Example

Use the [Reflect] trait to debug or recursively destructure any value.

pub struct Foo {
    a: u8
}

// initialize the debuginfo provider
let context = deflect::default_provider()?;

// create some type-erased data
let erased: Box<dyn Any> = Box::new(Foo { a: 42 });

// cast it to `&dyn Reflect`
let reflectable: &dyn deflect::Reflect = &erased;

// reflect it!
let value: deflect::Value = reflectable.reflect(&context)?;

// pretty-print the reflected value
assert_eq!(value.to_string(), "box Foo { a: 42 }");

// downcast into a `BoxedDyn` value
let value: deflect::value::BoxedDyn = value.try_into()?;

// dereference the boxed value
let value: deflect::Value = value.deref()?;

// downcast into a `Struct` value
let value: deflect::value::Struct = value.try_into()?;

// get the field `a` by name
let Some(field) = value.field("a")? else {
    panic!("no field named `a`!")
};

// get the value of the field
let value = field.value()?;

// downcast into a `u8`
let value: u8 = value.try_into()?;

// check that it's equal to `42`!
assert_eq!(value, 42);

See the examples directory of this crate's source for additional examples.

Limitations

The current implementation of [default_provider] only works when DWARF debuginfo is stored in the program's binary. It will not work if DWARF debug info is split into other files. Pull requests are welcome.

This crate is highly experimental. It is not suitable as a critical component of any system. The initial releases of this crate require significant polish. Pull requests are welcome. Its known soundness holes include ignorance of UnsafeCell. Don't reflect into types containing UnsafeCell.

Additionally, the particulars of how Rust encodes DWARF debug info my change over time. This crate will do its best to keep up with those changes. Again, pull requests are welcome.

License

This project is licensed under the Apache License, Version 2.0, or the MIT license, at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in deflect by you, shall be licensed as MIT and Apache 2.0, without any additional terms or conditions.

You might also like...
A library and binary for testing unhooking ntdll by identifying hooks via in-memory disassembly
A library and binary for testing unhooking ntdll by identifying hooks via in-memory disassembly

(First Public?) Sample of unhooking ntdll (All Exports & IAT imports) hooks in Rust using in-memory disassembly, avoiding direct syscalls and all hooked functions (incl. hooked NtProtectVirtualMemory)

CLI utility that screencaptures your Linux desktop and streams it to Kodi via UPNP/DLNA and RTSP

desktopcast Desktopcast is a little CLI application that allows you to cast your Linux desktop to any UPNP/DLNA device capable of the AVTransfer servi

Choose Rust types at compile-time via boolean constants

condtype Choose Rust types at compile-time via boolean constants, brought to you by Nikolai Vazquez. If you find this library useful, consider starrin

A tool to easily work with timezone lookups via a binary, a library, or a server.
A tool to easily work with timezone lookups via a binary, a library, or a server.

rtz A self-contained geo lookup library / binary / server for Rust / JS (via WASM) (free server) using data from the Natural Earth and OpenStreetMap d

Kubernetes operator for declaratively deploying wasmCloud applications (via wadm) and hosts on Kubernetes.

wasmcloud-operator An operator for managing a set of wasmCloud hosts running on Kubernetes and manage wasmCloud applications using wadm. The goal is t

Blaze is a Rust script that continuously monitors server resource usage and sends real-time summaries and alerts to a Discord channel via Webhook.
Blaze is a Rust script that continuously monitors server resource usage and sends real-time summaries and alerts to a Discord channel via Webhook.

Blaze Blaze is a Rust script designed to run 24/7 on a server, providing a summary of resource usage every 30 minutes (configurable) to a Discord chan

DWARF packaging utility, written in Rust, supporting GNU extension and DWARF 5 package formats.

thorin thorin is an DWARF packaging utility for creating DWARF packages (*.dwp files) out of input DWARF objects (*.dwo files; or *.o files with .dwo

DWARF packaging utility, written in Rust, supporting GNU extension and DWARF 5 package formats.

thorin thorin is an DWARF packaging utility for creating DWARF packages (*.dwp files) out of input DWARF objects (*.dwo files; or *.o files with .dwo

constduck: compile-time duck typing and reflection

constduck provides a procmacro that can enable compile time duck typing and reflection on arbitrary struct types.

A rust library that provides pseudo-reflection for structs and enums

Treeflection treeflection_derive Treeflection runs a command stored as a string on a tree of structs, collections and primitive types. Commands A comm

🪞 Powerful reflection library for Rust

🪞 mirror-mirror Powerful reflection library for Rust 🚨 Warning 🚨 This library is still experimental and should not be used for anything serious, ye

Rust Macros to automate the addition of Paths/Schemas to Utoipa crate, simulating Reflection during the compilation phase

utoipa_auto_discovery Rust Macros to automate the addition of Paths/Schemas to Utoipa crate, simulating Reflection during the compilation phase Crate

Generate CPU FlameGraphs based on DWARF Debug Info

torch A script that glues perf CPU sampling and Brendan Gregg's visualizer to generate FlameGraphs. Requirements Usage Examples License Requirements L

Dwarf Fortress inspired frontend to Veloren, the multiplayer RPG voxel game written in Rust
Dwarf Fortress inspired frontend to Veloren, the multiplayer RPG voxel game written in Rust

velobracket ('veloren' + 'bracket-lib') velobracket is Dwarf Fortress inspired frontend to Veloren, the multiplayer RPG voxel game written in Rust. Us

dwarf is a typed, interpreted, language that shares syntax with Rust.
dwarf is a typed, interpreted, language that shares syntax with Rust.

The dwarf Programming Language dwarf is a programming language based heavily upon, and implemented in, Rust. The language is interpreted (and slow) wi

Extract data from helium-programs via Solana RPC and serves it via HTTP

hnt-explorer This application extracts data from helium-programs via Solana RPC and serves it via HTTP. There are CLI commands meant to run and test t

Procedural engine sound generator controlled via GUI or CLI
Procedural engine sound generator controlled via GUI or CLI

enginesound GUI Application used to generate purely synthetic engine sounds with advanced options written in Rust loosely based on this paper Reading

FlatBuffers compiler (flatc) as API (with focus on transparent `.fbs` to `.rs` code-generation via Cargo build scripts integration)

FlatBuffers flatc API for Rust This crate provides a programmatical way to invoke flatc command (e.g. from build.rs) to generate Rust (or, in fact, an

PostgreSQL procedural language handler for Clojure via SCI

pl/sci Status This is very much an experiment and I'm open to feedback on where to take this next. Build Requirements lein GraalVM CE 20.3.0 Java 11 c

Comments
  • Use explicit `Debug` impls when available.

    Use explicit `Debug` impls when available.

    Deflect does not currently have any special handling of collection types (e.g., HashMap, Vec, etc.), so its Debug renderings of these types is very poor. Implementing custom reflections for these types is daunting.

    Instead, we should use the Debug impls of types when available, but how can we know the address of <T as Debug>::fmt? On zulip, @bjorn3 suggests:

    If it is already codegened, it may be possibly to get the name of this function using the symbol mangling rules and then dlsym it.

    Let's give this a shot. Some of the debug impl names are hidden and so aren't returned by dlsym. They are present in the ELF's symbol table though!

    opened by jswrenn 0
  • Distinguish between record structs, tuple structs, and unit structs.

    Distinguish between record structs, tuple structs, and unit structs.

    Deflect's pretty printing does not distinguish between record structs/variants, tuple structs/variants and unit structs/variants. This leads to some exceptionally ugly rendering of Option, Result, etc. Can we do better?

    There's nothing in the DWARF DIEs of these types that distinguishes them. This heuristic might be acceptable:

    • no fields: unit-like
    • fields are in the form __\d+: tuple-like
    • otherwise: struct-like
    opened by jswrenn 1
  • Serde support

    Serde support

    still todo:

    • [ ] make it an optional feature to reduce bloat
    • [ ] use field-name heuristics to select between serialize_struct and serialize_tuple_struct
    • [ ] tests!
    opened by jswrenn 0
  • Implement Serialize for Reflect?

    Implement Serialize for Reflect?

    I'd thought of building this kind of thing in the past so thanks a lot for making it!

    The use case that I had in mind was to be able to have serializable types for dumping program state without having to have the compile time and code size costs of #[derive(Serialize)]

    I haven't looked closely, but do you think that this would be possible to implement?

    opened by jrmuizel 1
Owner
Jack Wrenn
Jack Wrenn
dwarf is a typed, interpreted, language that shares syntax with Rust.

The dwarf Programming Language dwarf is a programming language based heavily upon, and implemented in, Rust. The language is interpreted (and slow) wi

Keith Star 17 Jul 12, 2023
Cli tool for git productivity written in Rust and packaged for consumption via NPM

crust ?? cli tool for git productivity written in Rust and packaged for consumption via NPM This repo is identical with @skyneticist/golee in terms of

null 2 Jul 30, 2022
Terminal text styling via ANSI escape sequences.

Iridescent Features iridescent is a library for styling terminal text easily. It supports basic ANSI sequences, Xterm-256 colors, and RGB. You can ope

Rob 2 Oct 20, 2022
🔔 CLI utility to send notifications to Slack via integration webhooks

Slack notifier Just a simple CLI tool to send notifications to Slack. Please note that this project is just a playground to start learning Rust, it is

Green.Mod 2 May 21, 2022
A tool to control the fan speed by monitoring the temperature of CPU via IPMI.

ipmi-fan-control A tool to control the fan speed by monitoring the temperature of CPU via IPMI. Why Our Dell R730 server's iDRAC is not works as expec

yinheli 9 Dec 29, 2022
Small microservice to render Lottie animation files via an http REST API.

Lottie Renderer Service Small microservice to render Lottie animation files via an http REST API. Run via docker docker run -p 8080:8080 ghcr.io/mikbo

Mikbot 3 Oct 22, 2022
Safe Unix shell-like parameter expansion/variable substitution via cross-platform CLI or Rust API

Safe Unix shell-like parameter expansion/variable substitution for those who need a more powerful alternative to envsubst but don't want to resort to

Isak Wertwein 4 Oct 4, 2022
🚀 A fast & easy way to interface w/ Farcaster.xyz via Rust 🦀

farcaster-rs ?? A simple & easy way to interface with Farcaster via Rust ?? Author: Landon Boles GitHub | Farcaster | Bird App Credits MistApproach To

Landon 29 Dec 15, 2022
MollySocket allows getting signal notifications via UnifiedPush.

MollySocket This software is still in alpha. MollySocket allows getting signal notifications via UnifiedPush. It works like a linked device, which doe

null 6 Dec 31, 2022
Process Injection via Component Object Model (COM) IRundown::DoCallback().

COM PROCESS INJECTION for RUST Process Injection via Component Object Model (COM) IRundown::DoCallback(). 该技术由 @modexpblog 挖掘发现,在我对该技术进行深入研究过程中,将原项目 m

Lane 7 Jan 20, 2023