Skip to content
This repository has been archived by the owner on Aug 22, 2024. It is now read-only.

libc::sysctlbyname doesn't show up in call graph output #1190

Closed
cdstanford opened this issue Nov 18, 2022 · 1 comment · Fixed by #1191
Closed

libc::sysctlbyname doesn't show up in call graph output #1190

cdstanford opened this issue Nov 18, 2022 · 1 comment · Fixed by #1191

Comments

@cdstanford
Copy link

cdstanford commented Nov 18, 2022

Issue

Hi, thank you for providing access to this excellent tool! In the following minimal example, libc::sysconf shows up in the call graph output, but libc::sysctlbyname doesn't. I haven't been able to track down why:

use core::ffi::CStr;
use core::ptr;

fn main() {
    unsafe {
        libc::sysconf(57);
        let hw_physicalcpu = CStr::from_bytes_with_nul(b"hw.physicalcpu\0").unwrap();
        libc::sysctlbyname(
            hw_physicalcpu.as_ptr(),
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null_mut(),
            0,
        );
    }
}

Here's the config.json file we're using to generate the call graph:

{
    "call_sites_output_path": "call_sites.json",
    "dot_output_path": "graph.dot",
    "reductions": [],
    "included_crates": [],
    "datalog_config": {
        "ddlog_output_path": "graph.dat",
        "type_map_output_path": "types.json",
        "datalog_backend": "DifferentialDatalog"
    }
}

Steps to Reproduce

  • Run cargo init in a new folder, then replace the main.rs file with the above code.
  • Add the config.json file to this folder
  • Set MIRAI_FLAGS to f"--call_graph_config config.json"
  • Then run cargo mirai and inspect the output graph.dot

Expected Behavior

In the graph.dot output (and call_sites.json as well), I expect to see a main function with call graph edges to both libc::sysconf and libc::sysctlbyname (as well as another edge, to CStr::from_bytes_with_nul).

Actual Results

Here's the call graph that is generated. It contains two of the expected edges, but libc::sysctlbyname is missing:

graph

And here's the raw graph.dot file:

digraph {
    0 [ label = "\"num_cpus_minimal::main\"" ]
    1 [ label = "\"libc::unix::{extern#1}::sysconf\"" ]
    2 [ label = "\"core::ffi::c_str::{impl#5}::from_bytes_with_nul\"" ]
    0 -> 1 [ ]
    0 -> 2 [ ]
}

I also took a look at call_sites.json, which contains an entry for libc.unix.foreign_1.sysconf, but nothing for sysctlbyname.

Environment

This is (possibly) MacOS specific code; I've only tested it on a mac (MacOS Monterey M1). But I think the libc function calls should show up regardless.

Rust version (rustc --version): rustc 1.64.0 (a55dd71d5 2022-09-19)

Possible explanations

I thought this might be due to code inlining, but I made a quick test file with #[inline(always)] and #[inline(never)] annotations, and both types of function calls show up.
It occurs to me that the syscall could be being optimized out prior to the MIR level, but that seems unlikely for this case.

Thank you and really appreciate any help that you can provide to diagnose this!

@cdstanford
Copy link
Author

cdstanford commented Nov 23, 2022

@hermanventer Thank you for responding and fixing this, much appreciated! We'll check out the latest commit.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant