Giter Site home page Giter Site logo

cargo-call-stack's People

Contributors

arcnmx avatar bors[bot] avatar dirbaio avatar hydra avatar japaric avatar jonas-schievink avatar kvinwang avatar nicholastmosher avatar thvdveld avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cargo-call-stack's Issues

Could not build call-stack graph

When trying to build the call-stack graph with cargo +nightly call-stack --target x86_64-unknown-linux-gnu --bin confertus > cg.dot on my project confertus, the following error resulted:

[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `_init`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `_init`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `_start`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `_start`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `deregister_tm_clones`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `deregister_tm_clones`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `register_tm_clones`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `register_tm_clones`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `__do_global_dtors_aux`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `__do_global_dtors_aux`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `frame_dummy`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `frame_dummy`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `__rust_probestack`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `__rust_probestack`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `__libc_csu_init`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `__libc_csu_init`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `__libc_csu_fini`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `__libc_csu_fini`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no stack usage information for `_fini`
[2022-07-14T11:51:44Z WARN  cargo_call_stack] no type information for `_fini`
thread 'main' panicked at 'BUG: callee `malloc` is unknown', /home/fkarg/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.11/src/main.rs:749:25

(It requested --target explicitly for some reason, I followed installation and example usage as written otherwise)

more of: error: failed to parse application's LLVM IR from...

Thank you for creating cargo-call-stack

$ cargo call-stack -V
cargo-call-stack 0.1.13

This is the error I see.
Looks like you have fixed some of them already.

error: failed to parse application's LLVM IR from `../target/x86_64-unknown-linux-gnu/release/deps/tlsserver_mio-75bdd8b69c4c59db.ll`: BUG: failed to parse LLVM IR; please submit a cargo-call-stack bug report and attach the `.ll` file: Failure("Eof in line 309009")

I believe the 2nd or third line is the cause. Full file also attached.

; Function Attrs: nonlazybind uwtable
define internal fastcc void @_ZN4ring2io10der_writer22write_positive_integer17h2cbd2a5c98e3e635E(ptr noundef nonnull align 1 %0, ptr noalias nocapture noundef readonly align 8 dereferenceable(24) %1, ptr %.0.val, i64 %.8.val) unnamed_addr #1 personality ptr @rust_eh_personality {
  %3 = icmp eq i64 %.8.val, 0
  br i1 %3, label %4, label %_ZN4ring2io8positive8Positive10first_byte17h8adc827486783c8bE.exit, !prof !4429

4:                                                ; preds = %2
; call core::panicking::panic_bounds_check
  tail call fastcc void @_ZN4core9panicking18panic_bounds_check17h4183f129c0f2d665E(i64 0, i64 0, ptr noalias noundef nonnull readonly align 8 dereferenceable(24) @anon.d6133c3b30208f5fca04db122d621065.14) #79, !noalias !51502
  unreachable

bad.txt.gz

build failure on stm32

While trying to run this on an STM32L0x project we get the following error:

$ cargo  +nightly call-stack --bin STM32_controller
   Compiling gimli v0.25.0
error[E0432]: unresolved import `alloc::sync`
 --> /Users/aholtzma/.cargo/registry/src/github.com-1ecc6299db9ec823/gimli-0.25.0/src/read/dwarf.rs:2:12
  |
2 | use alloc::sync::Arc;
  |            ^^^^ could not find `sync` in `alloc`

error[E0282]: type annotations needed
  --> /Users/aholtzma/.cargo/registry/src/github.com-1ecc6299db9ec823/gimli-0.25.0/src/read/dwarf.rs:97:18
   |
97 |             sup: None,
   |                  ^^^^ cannot infer type for type parameter `T` declared on the enum `Option`

error[E0283]: type annotations needed
  --> /Users/aholtzma/.cargo/registry/src/github.com-1ecc6299db9ec823/gimli-0.25.0/src/read/dwarf.rs:60:5
   |
21 | #[derive(Debug, Default)]
   |                 ------- in this derive macro expansion
...
60 |     pub sup: Option<Arc<Dwarf<R>>>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
   |
   = note: cannot satisfy `_: Default`
   = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0282, E0283, E0432.`

It's not clear what even uses gimli, so I'm a bit at a loss where to go from here.

intrinsic to direct call assumption could be less pessimistic

for this code:

#![no_main]
#![no_std]

use core::{cmp::Ordering, panic::PanicInfo};

#[no_mangle]
fn _start() -> (usize, usize) {
    (yes as usize, no as usize)
}

fn no(a: &str, b: &str) -> bool {
    if a.len() == 4 && b.len() == 4 {
        a.cmp(b) == Ordering::Equal
    } else {
        false
    }
}

fn yes(a: &str, b: &str) -> bool {
    a.cmp(b) == Ordering::Equal
}

#[panic_handler]
fn panic(_: &PanicInfo) -> ! {
    loop {}
}

call-stack v0.1.11 produces the following call graph

cg

if you look at the machine code, the function no does not call the memcmp function

000200f6 <app::no>:
   200f6:       4684            mov     ip, r0
   200f8:       2000            movs    r0, #0
   200fa:       2904            cmp     r1, #4
   200fc:       bf01            itttt   eq
   200fe:       2b04            cmpeq   r3, #4
   20100:       6810            ldreq   r0, [r2, #0]
   20102:       f8dc 1000       ldreq.w r1, [ip]
   20106:       1a08            subeq   r0, r1, r0
   20108:       bf04            itt     eq
   2010a:       fab0 f080       clzeq   r0, r0
   2010e:       0940            lsreq   r0, r0, #5
   20110:       4770            bx      lr

the LLVM IR does contain a call @memcmp and that's why call-stack adds that edge

; app::no
define internal noundef zeroext i1 @_ZN3app2no17hfff1cfbfed4433e3E ; etc.
  ; ..
  %_19.i.i.i = tail call i32 @memcmp ; etc.
  ; ..

in the particular case of Cortex-M where call-stack analyzes the machine code and sees no 'branch' instruction, call-stack should not add the edge

cc #63

stack usage mismatch assertion in core::fmt::write

Steps to reproduce

  1. set up app-template
  2. run cargo +nightly call-stack --target thumbv7em-none-eabihf --bin hello

Assertion

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `56`,
 right: `52`: BUG: LLVM reported that `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$9write_fmt17h0c40510e4e0a2d49E` uses 52 bytes of stack but this doesn't match our analysis', src/main.rs:1012:29

Machine code

$ arm-none-eabi-objdump -Cd target/thumbv7em-none-eabihf/release/hello
00000c9c <<&mut W as core::fmt::Write>::write_fmt>:
     c9c:   b5f0        push    {r4, r5, r6, r7, lr}
     c9e:   af03        add r7, sp, #12
     ca0:   f84d bd04   str.w   fp, [sp, #-4]!
     ca4:   b088        sub sp, #32
     ca6:   6800        ldr r0, [r0, #0]
     ca8:   aa02        add r2, sp, #8
     caa:   9001        str r0, [sp, #4]
     cac:   e891 5078   ldmia.w r1, {r3, r4, r5, r6, ip, lr}
     cb0:   4610        mov r0, r2
     cb2:   f241 319c   movw    r1, #5020   ; 0x139c
     cb6:   f2c0 0100   movt    r1, #0
     cba:   e880 5078   stmia.w r0, {r3, r4, r5, r6, ip, lr}
     cbe:   a801        add r0, sp, #4
     cc0:   f7ff fe78   bl  9b4 <core::fmt::write>
     cc4:   b008        add sp, #32
     cc6:   f85d bb04   ldr.w   fp, [sp], #4
     cca:   bdf0        pop {r4, r5, r6, r7, pc}

Support Raspberry RP2040 target?

For example:
https://github.com/embassy-rs/cyw43/tree/master/firmware this repo.

$ cargo call-stack --example rpi-pico-w --target RP2040 > cg.dot
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `/home/aaron/.cargo/bin/cargo-call-stack rustc - --crate-name ___ --print=file-names --target RP2040 --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (exit status: 1)
  --- stderr
  error: Error loading target specification: Could not find specification for target "RP2040". Run `rustc --print target-list` for a list of built-in targets

Where are the other functions?

I'm running a program for ARM target which calls function A, which calls B, and B calls B1 and B2. Each of those call B_end:

   A──►B┌─► B.1 ─► B_end
        │
        └─► B.2 ─► B_end

none of the fns are inline, when running cargo +nightly call-stack --bin <name>, I'm only getting:

name::B.2
name::B_end

where are the rest? are they inlined? I'm even seeing calls to other crates that they make but nothing else from my own crate.

BUG: unhandled llvm intrinsic: llvm.abs.i32

Hello!

I get the bug BUG: unhandled llvm intrinsic: llvm.abs.i32, when trying to execute the program on my project.

Test case:

git clone [email protected]:64kramsystem/catacomb_ii-64k.git
cd catacomb_ii-64k
cat >> Cargo.toml << TOML                                                 
[profile.release]
lto = true # "fat" yields the same problem
TOML
cargo +nightly call-stack --bin catacomb --target x86_64-unknown-linux-gnu

Output:

[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `_init`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `_init`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `_start`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `_start`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `deregister_tm_clones`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `deregister_tm_clones`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `register_tm_clones`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `register_tm_clones`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `__do_global_dtors_aux`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `__do_global_dtors_aux`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `frame_dummy`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `frame_dummy`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `__rust_probestack`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `__rust_probestack`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `__libc_csu_init`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `__libc_csu_init`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `__libc_csu_fini`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `__libc_csu_fini`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `atexit`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `__fstat`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `stat64`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `fstat64`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no stack usage information for `_fini`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] no type information for `_fini`
[2022-08-19T10:04:51Z WARN  cargo_call_stack] assuming that `llvm.umul.with.overflow.i64` directly lowers to machine code
thread 'main' panicked at 'BUG: unhandled llvm intrinsic: llvm.abs.i32', /home/saverio/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.11/src/main.rs:731:21
stack backtrace:
   0: rust_begin_unwind
             at /rustc/65f3f8b220f020e562c5dd848ff7319257a7ba45/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/65f3f8b220f020e562c5dd848ff7319257a7ba45/library/core/src/panicking.rs:107:14
   2: cargo_call_stack::run
   3: cargo_call_stack::main

"start" argument conflated with cargo subcommand

When cargo call-stack is called through cargo, the argv it sees is the unmodified `['cargo', 'call-stack', '--target', 'some-triple-triple', 'mystartsym']. Thus, the parser reports the start argument "mystartsym" as unexpected argument.

I'm not sure how this is best fixed; for a workaround, I'm calling it as ~/.cargo/bin/cargo-call-stack instad of cargo call-stack; this appears to necessitate setting a rustup override for nightly (as there is no place to put the +nightly).

Unexpected difference in LLVM and cargo-call-stack size for untyped functions

I have an application that triggers this assert in cargo-call-stack:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `0`,
 right: `8`: BUG: LLVM reported that `OUTLINED_FUNCTION_13` uses 0 bytes of stack but this doesn't match our analysis

originating from this code

                            // in all other cases our results should match

                            assert_eq!(
                                *llvm_stack, stack,
                                "BUG: LLVM reported that `{}` uses {} bytes of stack but \
                                 this doesn't match our analysis",
                                canonical_name, llvm_stack
                            );

Running objdump reveals the instructions for OUTLINED_FUNCTION_13:

0003fe96 <OUTLINED_FUNCTION_13>:
   3fe96: 4d f8 08 ed  	str	lr, [sp, #-8]!
   3fe9a: 50 46        	mov	r0, r10
   3fe9c: f0 f7 1a f8  	bl	0x2fed4 <core::cell::RefCell$LT$T$GT$::borrow_mut::hd9b9aa1e3adf77aa> @ imm = #-65484
   3fea0: 05 46        	mov	r5, r0
   3fea2: 04 30        	adds	r0, #4
   3fea4: 0e 46        	mov	r6, r1
   3fea6: ef f7 33 fa  	bl	0x2f310 <core::ptr::drop_in_place$LT$core..option..Option$LT$drogue_device..drivers..ble..mesh..config..network..Network$GT$$GT$::h7eb090b9876c8058> @ imm = #-68506
   3feaa: 28 46        	mov	r0, r5
   3feac: 59 46        	mov	r1, r11
   3feae: 4f f4 dc 72  	mov.w	r2, #440
   3feb2: 5d f8 08 eb  	ldr	lr, [sp], #8
   3feb6: 01 f0 27 b8  	b.w	0x40f08 <__aeabi_memcpy4> @ imm = #4174

And it looks like it is supposed to use 8 bytes of stack.

Is the correct way forward to modify the thumb.rs to catch this sp modification so that the calculated value is correct?

Parser has problems with nested parentheses in `define`s list of arguments

For example, if you try to analyze a program that uses panic_semihosting, or any other handler that uses PanicInfo, you'll get an error like this:

error:     --> 2270:1
     |
2270 | define internal fastcc void @_ZN4core9panicking9panic_fmt17h99ea3f713cb13aaeE(%"core::fmt::Arguments"* noalias nocapture dereferenceable(24), { [0 x i32], { [0 x i8]*, i32 }, [0 x i32], i32, [0 x i32], i32, [0 x i32] }* noalias nocapture readonly dereferenceable(16)) unnamed_addr #7 {
     | ^---
     |
     = expected EOI or item

The define rule doesn't properly handle parentheses inside the argument list.

assertion failure on ARM thumb

[2022-11-02T16:09:07Z WARN cargo_call_stack] assuming that asm!("push {lr}\0Asub sp, sp, #4\0Amov r2, sp\0Abl __udivmodsi4\0Aldr r1, [sp]\0Aadd sp, sp, #4\0Apop {pc}") does not use the stack in __aeabi_uidivmod
thread 'main' panicked at 'assertion failed: (left != right)
left: 14,
right: 14', /Users/aholtzma/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.12/src/thumb.rs:136:13
stack backtrace:
0: rust_begin_unwind
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:517:5
1: core::panicking::panic_fmt
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/panicking.rs:101:14
2: core::panicking::assert_failed_inner
3: core::panicking::assert_failed
4: cargo_call_stack::thumb::analyze
5: cargo_call_stack::run
6: cargo_call_stack::main

error: missing field `package`

I tried to use cargo-call-stack on a project that uses a workspace, and the only output I got was

error: missing field `package`

The only semi-related information I found on internet was this closed issue on cargo-binutils. It feels that the issue could be fixed by replacing cargo-project by cargo-metadata.

Supporting dynamic dispatch

Background information

This tool builds the call graph from LLVM IR.

Direct function calls look like this in LLVM IR.

  call fastcc void @_ZN6direct3foo17h2eeb2dcd0a346d49E(), !dbg !112

From the IR we know the name of the callee.

And indirect function calls look like this:

  %4 = tail call i32 %3({}* nonnull %0) #1, !dbg !354

There's not much information about the callee. We can't even tell if this is a trait object or a function pointer so the tool can't reason about indirect function calls.

Proposed rustc changes

Our proposal is to make rustc include type information as call-site metadata in the generated LLVM IR.

When trait objects are used the call site shall include metadata that specifies the name (path) of the trait and the name of the method being called.

; let x: &dyn path::to::Trait = ..;
; let y = x.method_name();
  %4 = tail call i32 %3({}* nonnull %0) #1, !dbg !354, !rust !123

!123 = !{!"path::to::Trait::method_name"}

When function pointers are used the call site shall include metadata that specifies the type signature of the function pointer.

; let x: fn() -> i32 = ..;
; let y = x();
  %4 = tail call i32 %3() #1, !dbg !354, !rust !234

!234 = !{!"fn() -> i32"}

Additionally, the definition of all trait methods should include metadata that specifies the name (path) of the trait and the name of the method.

; impl path::to::Trait for Type { fn method_name() { .. }}
define internal i32 @name() unnamed_addr #1 !dbg !216, !rust 123 {
  ..
}

!123 = !{!"path::to::Trait::method_name"}

And the definition of all functions shall include the metadata that specifies its type signature.

define internal i32 @name() unnamed_addr #1 !dbg !216, !rust 234 {
  ..
}

!234 = !{!"fn() -> i32"}

These metadata changes could be provided behind an unstable compiler flag (e.g. -Z emit-extra-metadata).

Changes in the tool

For each trait method implementation kept in the final binary the tool will insert an edge between that symbol and a node named, for example, dyn path::to::Trait::method_name.

  "dyn Trait::method" -> "<Type1 as Trait>::method"
  "dyn Trait::method" -> "<Type2 as Trait>::method"

The dyn nodes will be considered to have local stack usage of 0 bytes and each method call done through a trait object will be connected to one of these dyn nodes.

For each function definition kept in the final binary the tool will insert an edge between that symbol and a node named after its type signature, e.g. fn() -> i32.

  "fn() -> i32" -> "foo"
  "fn() -> i32" -> "bar"

The fn nodes will be considered to have local stack usage of 0 bytes and each function call done through a function pointer will be connected to one of these fn nodes.

Allow analysis of debug builds, not just release builds.

I have a use-case where I need to know how much MCU memory to devote to stack usage for code compiled in debug mode.

The tool currently always builds in release mode as it adds the --release argument to the rustc invocation.

Please can this restriction be changed? Maybe by way of a new command line argument that defaults to release mode? More specifically the cargo profile needs to be supported along with custom profiles.

See: https://doc.rust-lang.org/cargo/reference/profiles.html#custom-profiles

It seems there is some conditional code already that adds the --release argument, but the value it depends on is hard-coded.

See:
https://github.com/japaric/cargo-call-stack/blob/main/src/main.rs#L120
and
https://github.com/japaric/cargo-call-stack/blob/main/src/main.rs#L174-L176

BUG: failed to parse LLVM IR

Hello,

Error

I get the following message on my project

error: failed to parse application's LLVM IR from `project/target/x86_64-unknown-linux-gnu/release/deps/bin-0d269819aa1d3063.ll`: BUG: failed to parse LLVM IR; please submit a cargo-call-stack bug report and attach the `.ll` file: Failure("Eof in line 880")

Info

$ cargo +nightly call-stack  --version
cargo-call-stack 0.1.7
$ cargo --version
cargo 1.61.0 (a028ae4 2022-04-29)
$ rustc --version
rustc 1.61.0 (fe5b13d68 2022-05-18)

bin-0d269819aa1d3063.ll.txt

Let me know if I can help figuring it out.

thanks!

BUG: unhandled llvm intrinsic

My first attempt at using this tool failed with:

[...]
[2019-05-28T15:39:56Z WARN  cargo_call_stack] assuming that `llvm.umul.with.overflow.i64` directly lowers to machine code
thread 'main' panicked at 'BUG: unhandled llvm intrinsic: llvm.smul.with.overflow.i16', /home/dbonniot/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.3/src/main.rs:845:21

Seeing the previous warning for a similar intrinsic, I extended the list of intrinsics to avoid the panic. PR upcoming...

implicitly use the nightly channel

if you do this on stable

$ cargo call-stack --bin something

then cargo-call-stack will compile the entire dependency graph and fail at the last step saying -Z flag cannot be used on stable

a better user experience would be to implicitly compile the code using the nightly channel. if there's no nightly toolchain fail early before compiling anything.

parser error

The tool panics when it tries to analyze this program

#![no_std]
#![no_main]

extern crate panic_halt;

use core::sync::atomic::{AtomicU32, Ordering};

use cortex_m_rt::{entry, exception};

static X: AtomicU32 = AtomicU32::new(0);

#[entry]
fn main() -> ! {
    let x = X.load(Ordering::Relaxed);
    let y = foo(f32::from_bits(x)).to_bits();
    X.store(y, Ordering::Relaxed);

    loop {}
}

#[inline(never)]
fn foo(x: f32) -> f32 {
    x * 1.1
}

#[exception]
fn SysTick() {
    X.fetch_add(1, Ordering::Relaxed);
}

Any chance of supporting AVR?

I'm compiling rust code for AVR using avr-hal which uses avr-gcc for final compilation and bypasses LLVM. If I try:

$ cargo call-stack...

error: failed to parse application's LLVM IR from `/target/avr-atmega328p.json/release/deps/arduino_lib-3273400ccbbcd796.ll`: BUG: failed to parse LLVM IR; please submit a cargo-call-stack bug report and attach the `.ll` file: Failure("Eof in line 46")

file rename and attached: arduino_lib-3273400ccbbcd796.txt

BUG: expected a thumb tag at 0xacf9 but found another data tag

I am running call-stack towards a cortex-m4 target that uses a few cryptographic libraries (my repo is edhoc-rs).

When I run it, I get several warnings and then an error telling that it is a bug. Here are the relevant logs:

$ cd examples/edhoc-rs-no_std  # and then manually disable features I do not want enabled

$ cargo call-stack --target="thumbv7em-none-eabihf" --features="rust-psa, rtt" --bin edhoc-rs-no_std

  (... compilation logs ...)

[2023-05-02T09:57:33Z WARN  cargo_call_stack] no type information for `verify_header`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] no type information for `verify_chain`

  (... truncated ...)

[2023-05-02T09:57:33Z WARN  cargo_call_stack] no type information for `mbedtls_sha512_update`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] no type information for `mbedtls_sha512_finish`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] no type information for `mbedtls_sha512`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `rust_begin_unwind`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] assuming that asm!("push {r4, lr}\0Asub sp, sp, #16\0Aadd r4, sp, #8\0Astr r4, [sp]\0Abl __udivmoddi4\0Aldr r2, [sp, #8]\0Aldr r3, [sp, #12]\0Aadd sp, sp, #16\0Apop {r4, pc}") does *not* use the stack in `__aeabi_uldivmod`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `_ZN15edhoc_rs_no_std18__cortex_m_rt_main17h19cb218f62f79732E`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$9write_str17he7c9fdd55c30b43cE`
[2023-05-02T09:57:33Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$10write_char17h63faa3907ef7263bE`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `verify_chain`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `buffer_alloc_free`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] `buffer_alloc_free` performs an indirect function call and there's no type information about the operation
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `buffer_alloc_calloc`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] `buffer_alloc_calloc` performs an indirect function call and there's no type information about the operation
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `mbedtls_memory_buffer_alloc_init`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] `mbedtls_calloc` performs an indirect function call and there's no type information about the operation
[2023-05-02T09:57:34Z WARN  cargo_call_stack] `mbedtls_free` performs an indirect function call and there's no type information about the operation
[2023-05-02T09:57:34Z WARN  cargo_call_stack] `mbedtls_platform_zeroize` performs an indirect function call and there's no type information about the operation
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `psa_start_key_creation.constprop.0`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `psa_key_algorithm_permits`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `psa_get_and_lock_key_slot_with_policy.part.0`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `psa_cipher_setup`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `psa_verify_internal.part.0`
[2023-05-02T09:57:34Z WARN  cargo_call_stack] no stack usage information for `psa_validate_optional_attributes`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Data`,
 right: `Thumb`: BUG: expected a thumb tag at     0x71ed but found another data tag', /home/gfedrech/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cargo-call-stack-0.1.15/src/thumb.rs:60:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

And also another set of logs when I compile it using a different crypto backend (cryptocell instead of psa)

$ cd examples/edhoc-rs-no_std  # and then manually disable features I do not want enabled

$ cargo call-stack --target="thumbv7em-none-eabihf" --features="rust-cryptocell310, rtt" --bin edhoc-rs-no_std

  (... compilation logs ...)

[2023-05-02T10:02:21Z WARN  cargo_call_stack] no type information for `hashUpdate`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] no type information for `CRYS_HASH_Init`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] no type information for `CRYS_HASH_Update`

  (... truncated ... )

[2023-05-02T10:02:21Z WARN  cargo_call_stack] no type information for `SaSi_HalMaskInterrupt`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] no type information for `SaSi_HalWaitInterrupt`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] no type information for `SaSi_PalPowerSaveModeSelect`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$10write_char17h63faa3907ef7263bE`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `_ZN15edhoc_rs_no_std18__cortex_m_rt_main17h7519564f6efe4eb5E`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$9write_str17he7c9fdd55c30b43cE`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] assuming that asm!("bkpt #0xab") does *not* use the stack in `rust_begin_unwind`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] no stack usage information for `hashUpdate`
[2023-05-02T10:02:21Z WARN  cargo_call_stack] `hashUpdate` performs an indirect function call and there's no type information about the operation
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Data`,
 right: `Thumb`: BUG: expected a thumb tag at     0x5fad but found another data tag', /home/gfedrech/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cargo-call-stack-0.1.15/src/thumb.rs:60:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Also, in both cases, I updated the workspace's Cargo.toml to have lto = 'fat' in the release profile.

Failed to get bitcode from object file for LTO

When trying to use the tool I get the following error:

cargo +nightly call-stack --bin fedra --verbose

"cargo" "rustc" "--bin" "fedra" "--release" "--" "--emit=llvm-ir,obj" "-C" "embed-bitcode=yes" "-C" "lto=fat" "-Z" "emit-stack-sizes"
   Compiling fedra v0.1.0 (/Users/jiayihu/Desktop/Repo/fedra-clone)
error: failed to get bitcode from object file for LTO (Bitcode section not found in object file)
rustc --version
rustc 1.50.0-nightly (593fe977a 2020-11-20)

Same error even with the previous nightly rustc 1.49.0-nightly (b1496c6e6 2020-10-18)

How to run the examples?

First of all, I really appreciate what you are doing.

Problem

The readme describes how to run the examples.

There is a firmware/examples dir. I wonder if these are the examples that the readme is referring to? How do I run these examples?

I'm getting the same error as in #91

PROMPT> cargo +nightly call-stack --example app > cg.dot     
error: -Zbuild-std requires --target

I don't see any examples named app nor main.

I guess the way to use the examples are like this, but I'm getting the error: -Zbuild-std requires --target error.

PROMPT> pwd
/home/experiments/cargo-call-stack/firmware
PROMPT> cargo +nightly call-stack --example abs-i32 > cg.dot
error: -Zbuild-std requires --target

Proposal

Show how to run one of the example programs in greater detail.

JSON output + accompanying library

Being able to output JSON, instead of a .dot file, has a few uses:

  • it makes our unit tests more reliable: we would be able to use an API instead of text extraction / comparison
  • it lets other people perform post-analysis (using cargo xtask for example) relevant to their project. some use cases:
    • does the call graph that stems function X contain a cycle? e.g. does defmt::info-ing a recursive struct requires recursion?
    • can stack usage be upper bounded for this application? use CI to ensure it stays that way
    • is this application free from indirect function calls?
    • RTIC apps contain disconnected components due to the presence of interrupt handlers thus stack cannot be upper bounded for the whole app. with call-stack data + RTIC metadata it should be possible to compute the whole-app stack usage
  • plug the data into different visualization format. dot's PNG/SVG output is pretty cluttered and hard to read. using something interactive that limits the number of nodes that are displayed at once (e.g. only show a center node and its immediate neighbors) would make the data easier to digest.

we can probably just serialize a petgraph data structure into JSON to begin with. the node "weight" struct should contain at least this information:

struct Node {
   cumulative_stack_usage: Option<u64>,
   kind: NodeKind,
   local_stack_usage: Option<u64>,
   unmangled_name: String,
}

enum NodeKind {
    // matches to a symbol / routine in machine code
    Concrete,

    // "fictious" node that represents trait object dynamic dispatch
    DynamicDispatch { signature: String },

    // "fictious" node that represents function pointer calls
    FunctionPointer { signature: String },
}

Panic!() Function in Analyzed Code causes Assertion Errors in Cargo-Call-Stack

When I was trying Cargo-Call-Stack in my project, it failed with the following error message:

...
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `56`,
 right: `52`: BUG: LLVM reported that `_ZN50_$LT$$RF$mut$u20$W$u20$as$u20$core..fmt..Write$GT$9write_fmt17h0763000cb7e29fb5E` uses 52 bytes of stack but this doesn't match our analysis', .../.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.4/src/main.rs:1001:29

I could narrow down this problem and found that it seems to be related to the panic-handler implementations that several crates offer for embedded development. Comparing the four options listed in the Embedded Rust Book, I got the results that I documented in the following example code:

#![no_main]
#![no_std]

use cortex_m_rt::entry;
extern crate nucleo_f401re;

use panic_semihosting as _; // cargo-call-stack assertion error
//use panic_itm as _;       // cargo-call-stack assertion error
//use panic_halt as _;      // OK
//use panic_abort as _;     // OK

#[entry]
fn main() -> ! {
    panic!("Test panic behavior.");
}

I do not know if there is a simple explanation why this has to fail there or if that is a bug, I just wanted to let you know. If you need further information, please let me know. If it is of any help, my current setup is:

  • rustc 1.45.0-nightly (769d12eec 2020-05-12) OR rustc 1.43.1 (8d69840ab 2020-05-04)
  • cargo 1.45.0-nightly (cb06cb269 2020-05-08) OR cargo 1.43.0 (2cbe9048e 2020-05-03)
  • cargo-call-stack 0.1.4

Leverage `!callees` metadata

This program:

static X: AtomicBool = AtomicBool::new(false);

#[entry]
#[inline(never)]
fn main() -> ! {
    let mut x: fn() -> u32 = foo;

    if X.load(Ordering::Acquire) {
        x = bar;
    }

    x();
    baz();

    loop {}
}

fn foo() -> u32 {
    unsafe { asm!("" : : "r"(0) "r"(1) "r"(2) "r"(3) "r"(4) "r"(5)) }

    0
}

fn bar() -> u32 {
    unsafe { asm!("" : : "r"(0) "r"(1) "r"(2) "r"(3) "r"(4) "r"(5) "r"(6) "r"(7)) }

    1
}

#[inline(never)]
fn baz() -> u32 {
    // NOTE(asm!) side effect to preserve function calls to this method
    unsafe { asm!("NOP" : : : : "volatile") }

    2
}

#[exception]
fn SysTick() {
    X.store(true, Ordering::Relaxed);
}

Produces the following LLVM IR:

; Function Attrs: noinline noreturn nounwind
define void @main() unnamed_addr #2 !dbg !107 {
  ; ..

; `x();`
  %2 = tail call i32 %spec.select() #8, !dbg !138, !callees !139

; call app::baz
  tail call fastcc void @_ZN3app3baz17h9f37979edaee3ecdE(), !dbg !140
  
  ; ..
}

!139 = !{i32 ()* @_ZN3app3bar17hc173e5a24b32a7e4E, i32 ()* @_ZN3app3foo17h0c16cfbad983ef03E}

The function pointer call x() shows up as an indirect function call but the list of possible callees (foo and bar) are listed in metadata !callees !139.

We can use this information to get the exact list of candidates for some function pointer calls -- right now we are using the LLVM types to build the list of candidates but these can result in many false positives.

error[E0463]: can't find crate for panic_abort" on ESP32-C3

Hi,

When trying to run call stack for my ESP32-C3 I get the error "error[E0463]: can't find crate for panic_abort"

The command I run is cargo +nightly call-stack --bin my_bin --target riscv32imc-esp-espidf > cg.dot

In my cargo config I already have the corresponding options for build-std set:

[unstable]
build-std = ["panic_abort", "std"]
build-std-features = ["panic_immediate_abort"]

An also tried the -Z build-std=panic_abort,std parameters suggested in other issues.
I see that panic_abort is built:
Compiling panic_abort v0.0.0 (/Users/user/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/src/rust/library/panic_abort)
but when it is almost done compiling, it will throw the above error.

Is there any fix for this?

[feature request] Support C/C++ Clang projects

I'm not sure if this is feasible, but since this project uses the LLVM output in the .stack-size section of the ELF binary, is there any technical reason why this wouldn't work for C/C++ compiled with Clang?

LLVM reported that `__aeabi_memcpy` uses 0 bytes of stack but this doesn't match our analysis

I tried analyzing the cortex-m-test crate, more specific the hello example and cargo-call-stack panicked.

Compiled with:

  • rustc version: 1.57.0-nightly (2021-09-12)
  • target: thumbv7m-none-eabi

executed command:

cargo +nightly-2021-09-12 call-stack --target thumbv7m-none-eabi --example hello

And I got the following:

[2021-09-16T07:20:37Z WARN  cargo_call_stack] ad-hoc: injecting stack usage information for `__aeabi_memcpy` (last checked: Rust 1.33.0)
[2021-09-16T07:20:37Z WARN  cargo_call_stack] ad-hoc: injecting stack usage information for `__aeabi_memcpy4` (last checked: Rust 1.33.0)
[2021-09-16T07:20:37Z WARN  cargo_call_stack] no type information for `memcpy`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `16`,
 right: `0`: BUG: LLVM reported that `__aeabi_memcpy` uses 0 bytes of stack but this doesn't match our analysis', ~/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.5/src/main.rs:1003:29

I recognized that this could happen in the future, as it said in the README.

I tried it with older versions and recognized that in version 1.53.0-nightly I only get the warnings, but it compiles.

[2021-09-16T09:28:08Z WARN  cargo_call_stack] ad-hoc: injecting stack usage information for `__aeabi_memcpy` (last checked: Rust 1.33.0)
[2021-09-16T09:28:08Z WARN  cargo_call_stack] ad-hoc: injecting stack usage information for `__aeabi_memcpy4` (last checked: Rust 1.33.0)

When I use the version 1.54.0-nightly and above I get the panicking from above.

stack size unreachable error

I tried the cargo call-stack and this error happened:

thread 'main' panicked at 'internal error: entered unreachable code', /home/my-user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/stack-sizes-0.5.0/src/lib.rs:311:17

Infos:

  • RTIC v2
  • target: thumbv6m-none-eabi
  • cargo 1.72.0-nightly (5b377cece 2023-06-30)

src/main.rs not applicable?

I got this error:

$cargo call-stack > cg.dot

error: Please specify either --example <NAME> or --bin <NAME>.

Support static libraries

When building together with an external runtime, the builds cargo produces are static libraries (which are then linked by the runtime, eg. when using riot-wrappers). Could cargo-call-stack be modified to cater for those cases?

I've got it to load cdylibs partially with the attached patch (feeding it my staticlib declared as cdylib), but got stuck when ".stack_sizes section not found".

BUG? no symbol at address <xyz>

Analyzing an example built from a stm32f4 project. It requires linking to a C library, which I mocked out by declaring void symbol_name_here(void) {} for every needed symbol (because the real thing links the other way, using the crate as a staticlib -- and my attempts to make Rust link everything correctly have failed). So that could plausibly have something to do with it.

cargo +nightly call-stack --example ex --features=... --target=thumbv7em-none-eabihf returns:

thread 'main' panicked at 'BUG? no symbol at address 146572', /Users/matejcik/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.11/src/main.rs:970:48
stack backtrace:
   0: rust_begin_unwind
             at /rustc/263edd43c5255084292329423c61a9d69715ebfa/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/263edd43c5255084292329423c61a9d69715ebfa/library/core/src/panicking.rs:142:14
   2: cargo_call_stack::run::{{closure}}
   3: cargo_call_stack::run
   4: cargo_call_stack::main

binary is here: https://easyupload.io/dj57kq
output of objdump -D is here: https://pastebin.mozilla.org/E4DoW44B

it appears that there is indeed no symbol at address 146572, or 0x23c8c:

00023c54 <_ZN4core3str19slice_error_fail_rt17h8803d315cd910966E>:
(...)
   23c86:	2401      	movgt	r4, #1
   23c88:	f104 0cfd 	add.w	ip, r4, #253	; 0xfd
   23c8c:	f910 400c 	ldrsb.w	r4, [r0, ip]
   23c90:	f114 0f41 	cmn.w	r4, #65	; 0x41
(...)

i can do more debugging if you give me some pointers, at this point I have zero idea where to start.

`cargo-call-stack` fails to parse

When trying to run this project through cargo-call-stack, an error is produced.
The error message instructs me to include the first define item, but it's pretty long. I've included it in the repository for easier access, here.

My cargo version is 1.54.0-nightly (e51522ab3 2021-05-07), rustc 1.54.0-nightly (5c0292654 2021-05-11) and cargo-call-stack 0.1.5

I've tried to figure out what is going wrong, and where, but am having a hard time figuring out how to get some more useful output out of nom/the program besides the entire define block.

A fix, or pointers on how to figure out where exactly the error is occurring, are greatly appreciated!

failed to parse .ll file

When I run

cargo +nightly call-stack --bin my-binary

I get:

error: BUG: failed to parse .ll file; please submit a bug report. Details:
Error(Code(CompleteStr("…

followed by 177 megabytes of code. Pasting that much into a bug report probably wouldn't be helpful. Besides, this project contains some proprietary code, so I'm not allowed to disclose all of it.

Perhaps you could change this error case to quote the unparsable input more precisely?

error: Did not find ELF magic number

Great idea for a tool. A welcome addition.

I'm on a mac M1, with the target set accordingly. I tried to run a small app that failed. This may be just an FYI given the nightly changes etc.. but wanted to share nonetheless.

v1.72.0-nightly

fn main() {
    let hello_world = HelloWorld {
        message: Message::HelloWorld,
    };
    println!("{:#?}", hello_world)
}
> cargo +nightly call-stack --bin fun > cg.got
error: Did not find ELF magic number

The lto is set to 'fat', the target is set in my cargo config...

unexpected argument when defining start point

I am trying to define a start point bit the argument isn't recognized:

cargo +nightly call-stack --target="armv7a-none-eabi" --example=stack-call main > cg.dot
error: unexpected argument 'main' found

Usage: cargo-call-stack [OPTIONS] [START]

For more information, try '--help'.

thread 'main' panicked at 'BUG: callee `XYZ` is unknown' / (minimally) handle dynamically linked binaries

dynamically linked binaries contain 'undefined' symbols

$ file hello
hello: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2

$ nm -CSn hello
                 U abort@GLIBC_2.2.5
                 U bcmp@GLIBC_2.2.5
                 U calloc@GLIBC_2.2.5
(..)

these symbols are provide at runtime by a dynamic linker (e.g. /lib/ld-linux.so.2). Therefore cargo-call-stack, a static analysis tool, cannot provide a complete call graph for these kind of binaries.

Currently cargo-call-stack panics when it sees these kind of binaries. We should more gracefully handle these binaries by adding a dummy node that represents the dynamic libraries provided by the environment (dynamic linker) to the call graph and having all calls into 'undefined' symbols be connected to that dummy node.

It's not possible to provide a max stack usage number for dynamically linked binaries so that should also be reported to the console.

Workaround

If you are hitting the "thread 'main' panicked at 'BUG: callee XYZ is unknown'" error message try using a compilation target that produces a statically linked binary. If you were using x86_64-unknown-linux-gnu then use x86_64-unknown-linux-musl.

Yet another "failed to parse .ll file"

I'm sorry to say that I'm running into another parser error. On the fn example:

Failure(("%0 = type { [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32], i32, [0 x i32] } ...

on cargo-call-stack version 0.1.5 with cargo 1.48.0-nightly (9d1a4863a 2020-10-05).

I get exactly the same error and first definition (although shorter output) on the minimal no-std rust program:

#![no_main]
#![no_std]

use cortex_m_rt::entry;

#[inline(never)]
#[entry]
fn main() -> ! {
    loop {}
}

#[panic_handler]
fn phandler(_: &core::panic::PanicInfo) -> ! {
    loop {}
}

I would be happy to try and fix this error myself, but I'm really not sure where to start. If I don't get more specific guidance I'll try adding a bunch of debugging print statements tomorrow after work to see if I can track down what's causing this.

Add support for shared libraries?

I have a crate which compiles into a shared library (i.e. cdylib). It would be really useful to analyze stack usage of its functions, but currently this utility supports only binaries.

get type information from compiler-builtins LLVM IR

These warnings are common:

 no type information for `memset`

the underlying issue is that these "intrinsics" (subroutines) come from compiler-builtins, whose LLVM IR is NOT included in the output of cargo rustc -- --emit=llvm-ir because compiler-builtins is always linked in as a separate object file

the current workaround is to hard code the type information for these intrinsics in cargo-call-stack

but now that we are using a custom rustc wrapper to get stack usage from compiler-builtins it should be possible to compile compiler-builtins with --emit=llvm-ir. That should produce a separate LLVM IR file from which we could extract type information

BUG: callee `memcmp` is unknown

With the latest version (0.1.10), and from the main branch, I'm getting this error when running call-stack:

thread 'main' panicked at 'BUG: callee `memcmp` is unknown', /home/lulf/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-call-stack-0.1.10/src/main.rs:741:25

Example reproducer:

git clone https://github.com/lulf/embassy.git
cd embassy/examples/stm32wl
git checkout call-stack
git submodule update --init
cargo call-stack --bin lorawan

Failed to parse .ll file in v0.1.4

As recommend in #16 I'm opening a new issue.

$ cargo call-stack --version
cargo-call-stack 0.1.4

$ rustc +nightly --version
rustc 1.43.0-nightly (3dbade652 2020-03-09)
$ # Also tried with a 1.42 nightly before updating

Source code where the error occurs:
https://github.com/thalesfragoso/at28c-rs/blob/master/at28c-rs-firmware/src/main.rs

Error:

Failure(("define void @USB_LP_CAN_RX0() unnamed_addr #1 !dbg !13720 {\nstart:\n %0 = alloca [7 x i8], align 1\n %1 = alloca [16 x i8], align 1\n %input.sroa.8.i.i.i.i.i = alloca [3 x i8], align 1\n call void @llvm.dbg.declare(metadata [3 x i8]* %input.sroa.8.i.i.i.i.i, metadata !13721, metadata !DIExpression(DW_OP_LLVM_fragment, 40, 24)), !dbg !13758\n call void @llvm.dbg.declare(metadata [3 x i8]* %input.sroa.8.i.i.i.i.i, metadata !13721, metadata !DIExpression(DW_OP_LLVM_fragment, 40, 24)), !dbg !13830\n call void @llvm.dbg.declare(metadata [3 x i8]* %input.sroa.8.i.i.i.i.i, metadata !13721, metadata !DIExpression(DW_OP_LLVM_fragment, 40, 24)), !dbg !13833\n %_24.i3.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>::Ok", align 4\n %_16.sroa.4.i.i.i.i = alloca %"generic_array::GenericArrayImplEven<core::mem::maybe_uninit::MaybeUninit, generic_array::GenericArrayImplEven<core::mem::maybe_uninit::MaybeUninit, generic_array::GenericArrayImplEven<core::mem::maybe_uninit::MaybeUninit, generic_array::GenericArrayImplEven<core::mem::maybe_uninit::MaybeUninit, generic_array::GenericArrayImplEven<core::mem::maybe_uninit::MaybeUninit, generic_array::GenericArrayImplEven<core::mem::maybe_uninit::MaybeUninit, generic_array::GenericArrayImplOdd<core::mem::maybe_uninit::MaybeUninit, ()>>>>>>>", align 4\n %_7.i69.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i48.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i43.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i38.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i33.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i23.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i18.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i9.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_5.i.i.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_7.i.i.i.i.i.i.i34.i.i.i.i = alloca i16, align 2\n %writer.i.i.i.i53.i.i.i.i.i.i = alloca %"usb_device::descriptor::DescriptorWriter", align 4\n %writer.i.i.i.i34.i.i.i.i.i.i = alloca %"usb_device::descriptor::DescriptorWriter", align 4\n %writer.i.i.i.i17.i.i.i.i.i.i = alloca %"usb_device::descriptor::DescriptorWriter", align 4\n %bw.i.i.i.i.i.i.i.i.i.i.i = alloca %"usb_device::descriptor::BosWriter", align 4\n %writer.i.i.i.i1.i.i.i.i.i.i = alloca %"usb_device::descriptor::DescriptorWriter", align 4\n %_99.i.i.i.i.i = alloca [1 x i8], align 1\n %_91.i.i.i.i.i = alloca [1 x i8], align 1\n %_77.i.i.i.i.i = alloca i16, align 2\n %_60.i.i.i.i.i = alloca i16, align 2\n %_51.i.i.i.i.i = alloca i16, align 2\n %_35.i24.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_28.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>", align 4\n %_7.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>::Ok", align 4\n %_3.i.i.i.i.i = alloca %"core::result::Result<usize, usb_device::UsbError>::Ok", align 4\n %_53.i.i.i.i = alloca %"usb_device::control::Request", align 4\n %_45.i.i.i.i = alloca %"usb_device::control::Request", align 4\n %_102.i.i.i = alloca [1 x i8], align 1\n %_97.i.i.i = alloca %"core::result::Result<usize, usbd_serial::pool_serial::PoolError>", align 4\n %_10.i.i.i = alloca [1 x { {}, [3 x i32] }], align 4\n call void @llvm.dbg.value(metadata i8 2, metadata !13824, metadata !DIExpression()) #9, !dbg !13836\n %2 = tail call zeroext i8 @__basepri_r() #9, !dbg !13837\n call void @llvm.dbg.value(metadata i8 %2, metadata !13826, metadata !DIExpression()) #9, !dbg !13844\n call void @llvm.dbg.value(metadata %"usb_device::device::UsbDevice<stm32_usbd::bus::UsbBus<stm32f1xx_hal::usb::Peripheral>>"* bitcast (<{ [228 x i8] }>*
@_ZN17at28c_rs_firmware3APP7usb_dev17h3b2c007b3bb4f57bE to
...

I also tried +nightly-2018-12-27 as recommended in the previous issue, but then the compilation fails due to MaybeUninit and other things.

assertion with 64-bit division

Source code

static X: AtomicUsize = AtomicUsize::new(0);

#[entry]
fn main() -> ! {
    X.store(div64 as usize, Ordering::Relaxed);

    loop {}
}

fn div64(x: u64, y: u64) -> u64 {
    x / y
}

#[exception]
fn SysTick() {
    X.fetch_add(1, Ordering::Relaxed);
}

Error message

2021-09-17T10:55:53Z WARN  cargo_call_stack] no type information for `_ZN17compiler_builtins3int19specialized_div_rem11u64_div_rem17hfa5cc727e5163f40E`
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `8`,
 right: `24`: BUG: LLVM reported that `__aeabi_uldivmod` uses 8 bytes of stack but this doesn't match our analysis', src/main.rs:962:29

Machine code

000004ec <__aeabi_uldivmod>:
 4ec:   b510        push    {r4, lr}
 4ee:   b084        sub sp, #16
 4f0:   ac02        add r4, sp, #8
 4f2:   9400        str r4, [sp, #0]
 4f4:   f000 f925   bl  742 <__udivmoddi4>
 4f8:   9a02        ldr r2, [sp, #8]
 4fa:   9b03        ldr r3, [sp, #12]
 4fc:   b004        add sp, #16
 4fe:   bd10        pop {r4, pc}

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.