Giter VIP home page Giter VIP logo

Comments (34)

Milo123459 avatar Milo123459 commented on July 3, 2024 12

I tried. It's hard

from cargo-bloat.

Boscop avatar Boscop commented on July 3, 2024 7

@johnhe-indeed Any update on this? :)

from cargo-bloat.

Milo123459 avatar Milo123459 commented on July 3, 2024 6

Cool! I'll use the PDB crate. Hope I can get this working! 🎉

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024 4

@albru123 Done.

from cargo-bloat.

johnhe-indeed avatar johnhe-indeed commented on July 3, 2024 2

Hey @RazrFalcon, it's actually a COM api. It can be called from C or C++ and it wouldn't require installing anything afaik. The objects should be present on the default install of windows. The winapi rust crate does provide wrappers to make calling COM objects easier, so that may be useful and would avoid having to write bindings to C/C++ directly. Additionally, the WinAPI crate also has bindings to the dbghelp.dll, which could be an alternative approach. The COM APIs just use this DLL under the hood, iirc.

I may take a stab at this, if you think it would be useful for your project (Or I may just contribute to the PDB Crate, depending on what makes more sense after I conduct more research). I'm interested in learning how to call COM/WinAPIs from rust for another project and this would be good practice.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024 1

MinGW target is supported now. MSVC is still not possible, because PDB isn't documented and I have no idea how to retrieve the symbol sizes.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024 1

@johnhe-indeed I would not mind some help. I have a prototype that uses the pdb crate, but the total symbols size I'm getting is bigger that the executable itself. So something is calculated incorrectly. PDB contains too much information and I'm not sure how to filter it. And this is the main problem.

The task itself is pretty straightforward: split the .text section of the binary into symbols. So it will look like this:

Start End Size Name
0 10 10 main
10 25 15 some_method
. . . etc...

from cargo-bloat.

johnhe-indeed avatar johnhe-indeed commented on July 3, 2024 1

Okay, I spent a few hours this morning playing with this. I ended up just using the PDB rust library, mentioned earlier in this thread. It should meet all your requirements and is cross-platform. I used the latest main branch, but this should work using 0.5.0, with slightly different type names. The sample, pdb_symbols has all the parts you really need to make this work.

Couple of notes, you'll want to walk the private modules dictionary to get the information you're after with the procedure symbols.

In the sample, he walks them using this snippet:

 let dbi = pdb.debug_information()?;
 let mut modules = dbi.modules()?;
 while let Some(module) = modules.next()? {
         ...
 }
 walk_symbols(info.symbols()?)?;

walk_symbols just dumps the symbols from the modules.

For procedures it's pretty straight forward to get the size, and offset from the section. Note, the symbol may be in a different section, you will need to validate that with section number on the symbol is pointing to symbols .text. I dont know where that map is off the top of my head, but this library seems to have all the pieces.

In most cases symbols will be .text, but I think exception handlers are put in .rdata. To get the offset of the various sections such as .text in the actual .exe binary, I saw a PE header def in the library. The actual bytes for the symbol will be the section offset + offset in symbol.

See below:

  pdb::SymbolData::Data(data) => {
            //print_row(data.offset, "data", data.name);
        }
        pdb::SymbolData::Procedure(data) => {
            println!(
                "{}, offset: {:x}, len: {}",
                data.name, data.offset.offset, data.len
            );
            //print_row(data.offset, "function", data.name);
        }

I did a bunch of checks as well to validate the offsets and lengths using other tools. To validate the length was correct, I just loaded the binary in windbg with the symbols, did an x /f <program_name>!, which prints the same length in hex and matches the symbols dumped.

To validate the offset, I opened the .exe in IDA Pro, navigated to the function's bytes, and pulled enough of the function bytes to create a unique signature. I then went into 010 Hex editor, searched for the function bytes, got the raw offset inside the file. I also ran the PE header template to get the .text offset. Then it was just adding to the offset generated by the PDB rust library and text section offset and it matched the function bytes at the expected offset.

Hope this helps!

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

I need PDB support.

from cargo-bloat.

koutheir avatar koutheir commented on July 3, 2024

I need PDB support.

Would the pdb crate cover the project needs?

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

I will look into it.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

Waiting for getsentry/pdb#27

from cargo-bloat.

novacrazy avatar novacrazy commented on July 3, 2024

Has anything improved on this front?

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

@novacrazy I still have no idea how PDB works and I didn't have time to investigate it. Patches are welcome.

from cargo-bloat.

serak avatar serak commented on July 3, 2024

is your pdb dumper from llvm ?
https://llvm.org/docs/CommandGuide/llvm-pdbutil.html

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

@serak probably. I'm simply running cargo and it does its magic.

from cargo-bloat.

albertmoravec avatar albertmoravec commented on July 3, 2024

Might be a bit offtopic, but is there a reason for not supporting Windows even if I want to analyze an ELF binary? I wanted to use it in an embedded project that cross-compiles a binary for ARM, but it seems like a no-go.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

@albru123 This can be implemented.

from cargo-bloat.

smmalis37 avatar smmalis37 commented on July 3, 2024

I believe the officially supported way to examine PDB contents is through DIA: https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/debug-interface-access-sdk

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

@smmalis37 The problem is not to parse/query PDB, but to figure out what symbols are actually required and how to calculate their sizes.

Basically, I have to figure out how to split the .text section data into symbols.

from cargo-bloat.

johnhe-indeed avatar johnhe-indeed commented on July 3, 2024

I just kind of stumbled on this ticket, but have a lot of experience with PE files and debugging APIs in windows. The DIA Symbol interface should have the information you would need, unless I mis-understanding this ticket.

For example, here is the COM interface for a symbol in DIA. It has a lot of information about the symbol, including the virtual address offset, as well as the length in bits/bytes. You can even traverse a symbol and visit its children which might be useful for your scenario, if I understand it correctly.
https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/idiasymbol?view=vs-2015

Get-VA method (To find the symbol in the .text section of the binary).
https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/idiasymbol-get-virtualaddress?view=vs-2015

Get length of symbol in bits/bytes
https://docs.microsoft.com/en-us/visualstudio/debugger/debug-interface-access/idiasymbol-get-length?view=vs-2015

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

@johnhe-indeed Hi! If I understand correctly, this is a C++ API to work with PDB files. So to use it in this project I have to write a bindings first, which complicates things a bit. And I'm not sure if you can built it directly, without installing the SDK.

I will try to write a demo app in C++ first, but I prefer a pure rust implementation.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

Yeah, this is basically how it works right now. I do filter by section, etc. The hardest part is to actually write and debug it. Also, PDB stores demangled function names, which is problematic, because I have to parse them again and they can have different versions (legacy or v0).

I'll push a PDB branch later, so you can play with an actual code.

PS: I don't need absolute offset.

from cargo-bloat.

alilleybrinker avatar alilleybrinker commented on July 3, 2024

@RazrFalcon in the case of an unsupported format, could this be checked prior to running cargo build? Would save time if it's not going to work in the end.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

I don't thinks so. I don't know what cargo would be building beforehand. Unless we, somehow, can check what target will be used.

from cargo-bloat.

Milo123459 avatar Milo123459 commented on July 3, 2024

Any updates?

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

Unless someone will have time for a pull request, this will stay the same. I simply don't have time working on it.

from cargo-bloat.

Milo123459 avatar Milo123459 commented on July 3, 2024

Unless someone will have time for a pull request, this will stay the same. I simply don't have time working on it.

Okay, what would have to be implemented? I'll be more than happy to integrate this.

from cargo-bloat.

RazrFalcon avatar RazrFalcon commented on July 3, 2024

This was already discussed in this issues, see: #17 (comment)

The task is "simple": get a list of all functions and their sizes from the binary.

from cargo-bloat.

mat-gas avatar mat-gas commented on July 3, 2024

Hi @Milo123459 , any update on your progress using the pdb crate?

from cargo-bloat.

nico-abram avatar nico-abram commented on July 3, 2024

Hi, I wrote a test program to generate (length, demangled_name, Option(mangled_name)) tuples using the pdb crate. I also tried the symbolic crate but that just gave me unmangled names. If unmangled names end up being fine, the API for symbolic looks a bit nicer.

I cannot find unmangled names for all symbols, since to find them I'm trying to find a matching PublicSymbol record with the unmangled name, and it seems rustc is not generating those for all functions. Here's the output for cargo-bloat itself compiled in debug mode to get an idea of the ratios:

exe size:2179072
text size:1717760
size of fns found: 1638424
ratio:0.95381427
size of fns with mangles found: 1100283
ratio:0.6405336

And in release mode:

exe size:892416
text size:695808
size of fns found: 192204
ratio:0.27623138
size of fns with mangles found: 90109
ratio:0.12950268

code:

use pdb::FallibleIterator;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let dir = std::path::Path::new("D:\\your\\path\\to\\pdb\\folder");
    let file_name = "cargo-bloat";

    let exe_path = dir.join(file_name).with_extension("exe");
    let exe_size = std::fs::metadata(&exe_path)?.len();
    let (_, text_size) = binfarce::pe::parse(&std::fs::read(&exe_path).unwrap())?.symbols()?;

    let pdb_path = dir.join(file_name.replace("-", "_")).with_extension("pdb");
    let file = std::fs::File::open(&pdb_path)?;
    let mut pdb = pdb::PDB::open(file)?;

    let dbi = pdb.debug_information()?;
    let symbol_table = pdb.global_symbols()?;

    let mut total_parsed_size = 0usize;
    let mut demangled_total_parsed_size = 0usize;
    let mut out_symbols = vec![];

    // Collect the PublicSymbols
    let mut public_symbols = vec![];

    let mut symbols = symbol_table.iter();
    while let Ok(Some(symbol)) = symbols.next() {
        match symbol.parse() {
            Ok(pdb::SymbolData::Public(data)) => {
                if data.code || data.function {
                    public_symbols.push((data.offset, data.name.to_string().into_owned()));
                }
                if data.name.to_string().contains("try_small_punycode_decode") {
                    dbg!(&data);
                }
            }
            _ => {}
        }
    }

    let mut modules = dbi.modules()?;
    while let Some(module) = modules.next()? {
        let info = match pdb.module_info(&module)? {
            Some(info) => info,
            None => continue,
        };
        let mut symbols = info.symbols()?;
        while let Some(symbol) = symbols.next()? {
            if let Ok(pdb::SymbolData::Public(data)) = symbol.parse() {
                if data.code || data.function {
                    public_symbols.push((data.offset, data.name.to_string().into_owned()));
                }
                if data.name.to_string().contains("try_small_punycode_decode") {
                    dbg!(&data);
                }
            }
        }
    }

    let cmp_offsets = |a: &pdb::PdbInternalSectionOffset, b: &pdb::PdbInternalSectionOffset| {
        a.section.cmp(&b.section).then(a.offset.cmp(&b.offset))
    };
    public_symbols.sort_unstable_by(|a, b| cmp_offsets(&a.0, &b.0));

    // Now find the Procedure symbols in all modules
    // and if possible the matching PublicSymbol record with the mangled name
    let mut handle_proc = |proc: pdb::ProcedureSymbol| {
        let mangled_symbol = public_symbols
            .binary_search_by(|probe| {
                let low = cmp_offsets(&probe.0, &proc.offset);
                let high = cmp_offsets(&probe.0, &(proc.offset + proc.len));

                use std::cmp::Ordering::*;
                match (low, high) {
                    // Less than the low bound -> less
                    (Less, _) => Less,
                    // More than the high bound -> greater
                    (_, Greater) => Greater,
                    _ => Equal,
                }
            })
            .ok()
            .map(|x| &public_symbols[x]);
        // Uncomment to verify binary search isn't screwing up anything
        /*
        let mangled_symbol = public_symbols
            .iter()
            .filter(|probe| probe.0 >= proc.offset && probe.0 <= (proc.offset + proc.len))
            .take(1)
            .next();
        */

        let demangled_name = proc.name.to_string().into_owned();
        out_symbols.push((proc.len as usize, demangled_name, mangled_symbol));

        total_parsed_size += proc.len as usize;
        if mangled_symbol.is_some() {
            demangled_total_parsed_size += proc.len as usize;
        }
    };

    let mut symbols = symbol_table.iter();
    while let Ok(Some(symbol)) = symbols.next() {
        if let Ok(pdb::SymbolData::Procedure(proc)) = symbol.parse() {
            handle_proc(proc);
        }
    }
    let mut modules = dbi.modules()?;
    while let Some(module) = modules.next()? {
        let info = match pdb.module_info(&module)? {
            Some(info) => info,
            None => continue,
        };

        let mut symbols = info.symbols()?;

        while let Some(symbol) = symbols.next()? {
            if let Ok(pdb::SymbolData::Procedure(proc)) = symbol.parse() {
                handle_proc(proc);
            }
        }
    }

    println!(
        "exe size:{}\ntext size:{}\nsize of fns found: {}\nratio:{}\nsize of fns with mangles found: {}\nratio:{}",
        exe_size,
        text_size,
        total_parsed_size,
        total_parsed_size as f32 / text_size as f32,
        demangled_total_parsed_size,
        demangled_total_parsed_size as f32 / text_size as f32
    );

    /*
    // Test for the symbolic crate. It turns out it prints gives all the function names unmangled
    // which is the opposite of what we need

    use symbolic::common::{ByteView, Language, Name, NameMangling};
    use symbolic::debuginfo::{Function, Object};
    use symbolic::demangle::{Demangle, DemangleOptions};

    let view = ByteView::open(&pdb_path).expect("failed to open file");
    let object = Object::parse(&view).expect("failed to parse file");
    let session = object.debug_session().expect("failed to process file");
    for function in session.functions() {
        if let Ok(function) = function {
            if function.name.mangling() == symbolic::common::NameMangling::Unmangled {
                dbg!(function);
            }
        }
    }
    */

    Ok(())
}

I might try to add this to cargo-bloat in the following days. I will also be looking into ways of finding the mangled names, and also if I am correctly finding all the procedure symbols that I can (Looking in all modules and in the symbol table). If I don't post an update here in a week, please don't let me stop anyone else from working on this.

Related: getsentry/pdb#107

from cargo-bloat.

nico-abram avatar nico-abram commented on July 3, 2024

Is there a way to run cargo-bloat while developing? I'm getting "Error: can be run only via cargo bloat."

from cargo-bloat.

nico-abram avatar nico-abram commented on July 3, 2024

I just commented the eror lines. I got cargo-bloat to output this on itself:

D:\dev\cargo-bloat [master ≡ +0 ~3 -0 !]> cargo run ; cargo run --release -- --release
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target\debug\cargo-bloat.exe`
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
[src\main.rs:912] &pdb_path = "D:\\dev\\cargo-bloat\\target\\debug\\cargo_bloat.pdb"
    Analyzing target\debug\cargo-bloat.exe

 File  .text    Size        Crate Name
 1.1%   1.4% 28.1KiB         json json::parser::Parser::parse
 0.5%   0.7% 13.2KiB         json json::util::print_dec::write
 0.5%   0.6% 11.7KiB         json json::codegen::Generator::write_json
 0.3%   0.4%  8.0KiB          pdb <pdb::symbol::SymbolData as scroll::ctx::TryFromCtx>::try_from_ctx
 0.3%   0.4%  7.0KiB regex_syntax <regex_syntax::hir::translate::TranslatorI as regex_syntax::ast::visitor::Visitor>::visit_class_set_item_post
 0.3%   0.3%  6.6KiB regex_syntax <regex_syntax::hir::translate::TranslatorI as regex_syntax::ast::visitor::Visitor>::visit_post
 0.2%   0.3%  5.3KiB        regex regex::exec::ExecBuilder::build
 0.2%   0.3%  5.3KiB          std core::num::flt2dec::strategy::dragon::format_shortest
 0.2%   0.2%  4.7KiB regex_syntax alloc::str::join_generic_copy
 0.2%   0.2%  4.5KiB     binfarce <binfarce::demangle::legacy::Demangle as core::fmt::Display>::fmt
 0.2%   0.2%  4.4KiB     binfarce binfarce::pe::Pe::symbols
 0.2%   0.2%  4.4KiB          std core::num::flt2dec::strategy::dragon::format_exact
 0.2%   0.2%  4.0KiB         json json::object::Object::insert_index
 0.1%   0.2%  3.7KiB          pdb <pdb::common::Error as core::fmt::Debug>::fmt
 0.1%   0.2%  3.5KiB regex_syntax <regex_syntax::error::Formatter<E> as core::fmt::Display>::fmt
 0.1%   0.2%  3.5KiB regex_syntax <regex_syntax::error::Formatter<E> as core::fmt::Display>::fmt
 0.1%   0.2%  3.5KiB     binfarce binfarce::elf64::Elf64::symbols
 0.1%   0.2%  3.4KiB     binfarce binfarce::macho::Macho::find_section
 0.1%   0.2%  3.3KiB          std rustc_demangle::demangle
 0.1%   0.2%  3.2KiB cargo_bloat? <cargo_bloat::table::Table as core::fmt::Display>::fmt
47.3%  59.3%  1.1MiB              And 8776 smaller methods. Use -n N to show more.
79.6% 100.0%  1.9MiB              .text section size, the file size is 2.4MiB
    Finished release [optimized] target(s) in 0.02s
     Running `target\release\cargo-bloat.exe --release`
    Finished release [optimized] target(s) in 0.02s
[src\main.rs:912] &pdb_path = "D:\\dev\\cargo-bloat\\target\\release\\cargo_bloat.pdb"
    Analyzing target\release\cargo-bloat.exe

 File  .text     Size Crate Name
 0.6%   0.7%   5.3KiB   std core::num::flt2dec::strategy::dragon::format_shortest
 0.5%   0.6%   4.4KiB   std core::num::flt2dec::strategy::dragon::format_exact
 0.3%   0.4%   3.3KiB   std rustc_demangle::demangle
 0.3%   0.4%   3.1KiB   std <rustc_demangle::legacy::Demangle as core::fmt::Display>::fmt
 0.3%   0.4%   3.0KiB   std std::process::Child::wait_with_output
 0.3%   0.3%   2.5KiB   std <std::env::Args as core::iter::traits::iterator::Iterator>::next
 0.2%   0.3%   2.3KiB   std core::num::flt2dec::strategy::grisu::format_shortest_opt
 0.2%   0.2%   1.5KiB   std <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
 0.1%   0.2%   1.4KiB   std core::str::pattern::StrSearcher::new
 0.1%   0.2%   1.3KiB   std core::fmt::Formatter::pad_integral
 0.1%   0.2%   1.2KiB   std core::num::flt2dec::strategy::grisu::format_exact_opt
 0.1%   0.2%   1.2KiB   std std::path::Path::components
 0.1%   0.2%   1.2KiB   std <rustc_demangle::v0::Ident as core::fmt::Display>::fmt
 0.1%   0.2%   1.2KiB   std core::fmt::Formatter::pad
 0.1%   0.2%   1.2KiB   std <str as core::fmt::Debug>::fmt
 0.1%   0.2%   1.2KiB   std core::str::slice_error_fail
 0.1%   0.1%   1.1KiB   std core::num::bignum::Big32x40::mul_pow2
 0.1%   0.1%   1.1KiB   std <std::path::Components as core::iter::traits::iterator::Iterator>::next
 0.1%   0.1%   1.0KiB   std <std::io::error::Error as core::fmt::Display>::fmt
 0.1%   0.1%   1.0KiB   std <core::str::lossy::Utf8LossyChunksIter as core::iter::traits::iterator::Iterator>::next
 5.3%   6.8%  51.0KiB       And 260 smaller methods. Use -n N to show more.
78.3% 100.0% 748.0KiB       .text section size, the file size is 955.5KiB

from cargo-bloat.

nico-abram avatar nico-abram commented on July 3, 2024

Sent a pull request, here's the current output on cargo-bloat itself:

D:\dev\cargo-bloat [master ↑2]> cargo run ; cargo run --release -- --release
   Compiling cargo-bloat v0.10.1 (D:\dev\cargo-bloat)
    Finished dev [unoptimized + debuginfo] target(s) in 1.27s
     Running `target\debug\cargo-bloat.exe`
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
    Analyzing target\debug\cargo-bloat.exe

 File  .text    Size         Crate Name
 1.1%   1.4% 28.1KiB          json json::parser::Parser::parse
 0.5%   0.7% 13.2KiB          json json::util::print_dec::write
 0.5%   0.6% 11.8KiB  cargo_bloat? cargo_bloat::process_crate
 0.5%   0.6% 11.7KiB          json json::codegen::Generator::write_json
 0.5%   0.6% 11.6KiB          std? std::sys::windows::process::Command::spawn
 0.5%   0.6% 11.6KiB  cargo_bloat? cargo_bloat::parse_args
 0.4%   0.5% 10.6KiB  cargo_bloat? cargo_bloat::collect_pe_data
 0.3%   0.4%  8.0KiB           pdb <pdb::symbol::SymbolData as scroll::ctx::TryFromCtx>::try_from_ctx
 0.3%   0.4%  7.0KiB  regex_syntax <regex_syntax::hir::translate::TranslatorI as regex_syntax::ast::visitor::Visitor>::visit_class_set_item_post
 0.3%   0.3%  6.8KiB regex_syntax? regex_syntax::ast::parse::ParserI<ref_mut$<regex_syntax::ast::parse::Parser> >::parse_with_comments<ref_mut$<regex_syntax::ast::parse::Parser> >
 0.3%   0.3%  6.6KiB  regex_syntax <regex_syntax::hir::translate::TranslatorI as regex_syntax::ast::visitor::Visitor>::visit_post
 0.2%   0.3%  5.3KiB          std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,std::ffi::os_str::OsString>
 0.2%   0.3%  5.3KiB         regex regex::exec::ExecBuilder::build
 0.2%   0.3%  5.3KiB           std core::num::flt2dec::strategy::dragon::format_shortest
 0.2%   0.3%  5.3KiB          std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,enum$<core::option::Option<std::ffi::os_str::OsString>, 1, 1844674...
 0.2%   0.2%  4.7KiB  regex_syntax alloc::str::join_generic_copy
 0.2%   0.2%  4.5KiB      binfarce <binfarce::demangle::legacy::Demangle as core::fmt::Display>::fmt
 0.2%   0.2%  4.4KiB  cargo_bloat? cargo_bloat::main
 0.2%   0.2%  4.4KiB      binfarce binfarce::pe::Pe::symbols
 0.2%   0.2%  4.4KiB           std core::num::flt2dec::strategy::dragon::format_exact
69.2%  86.9%  1.7MiB               And 10270 smaller methods. Use -n N to show more.
79.6% 100.0%  1.9MiB               .text section size, the file size is 2.4MiB
   Compiling cargo-bloat v0.10.1 (D:\dev\cargo-bloat)
    Finished release [optimized] target(s) in 4.32s
     Running `target\release\cargo-bloat.exe --release`
    Finished release [optimized] target(s) in 0.02s
    Analyzing target\release\cargo-bloat.exe

 File  .text     Size Crate Name
 1.2%   1.6%  11.6KiB  std? std::sys::windows::process::Command::spawn
 0.6%   0.7%   5.3KiB  std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,std::ffi::os_str::OsString>
 0.6%   0.7%   5.3KiB   std core::num::flt2dec::strategy::dragon::format_shortest
 0.6%   0.7%   5.3KiB  std? alloc::collections::btree::map::BTreeMap::insert<std::sys::windows::process::EnvKey,enum$<core::option::Option<std::ffi::os_str::OsString>, 1, 18446744073709...
 0.5%   0.6%   4.4KiB   std core::num::flt2dec::strategy::dragon::format_exact
 0.4%   0.5%   3.8KiB  std? rustc_demangle::v0::Printer::print_type
 0.3%   0.4%   3.3KiB   std rustc_demangle::demangle
 0.3%   0.4%   3.2KiB  std? std::sys::windows::process::Stdio::to_handle
 0.3%   0.4%   3.1KiB   std <rustc_demangle::legacy::Demangle as core::fmt::Display>::fmt
 0.3%   0.4%   3.0KiB   std std::process::Child::wait_with_output
 0.3%   0.4%   2.9KiB  std? rustc_demangle::v0::Printer::print_const
 0.3%   0.3%   2.6KiB  std? rustc_demangle::v0::Printer::print_path
 0.3%   0.3%   2.5KiB   std std::env::args_os
 0.2%   0.3%   2.3KiB   std core::num::flt2dec::strategy::grisu::format_shortest_opt
 0.2%   0.3%   2.1KiB  std? std::sys::windows::process::make_command_line::append_arg
 0.2%   0.2%   1.6KiB  std? std::backtrace_rs::print::BacktraceFrameFmt::print_raw_with_column
 0.2%   0.2%   1.6KiB  std? alloc::collections::btree::node::Handle::remove_leaf_kv<std::sys::windows::process::EnvKey,std::ffi::os_str::OsString,alloc::collections::btree::map::entry::...
 0.2%   0.2%   1.5KiB  std? std::panicking::default_hook
 0.2%   0.2%   1.5KiB   std <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
 0.2%   0.2%   1.5KiB  std? rustc_demangle::v0::impl$6::print_type::closure$0
12.6%  16.2% 121.3KiB       And 518 smaller methods. Use -n N to show more.
78.2% 100.0% 751.0KiB       .text section size, the file size is 960.5KiB

from cargo-bloat.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.