`libc::sysctlbyname` doesn't show up in call graph output
cdstanford opened this issue · 1 comments
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 themain.rs
file with the above code. - Add the
config.json
file to this folder - Set
MIRAI_FLAGS
tof"--call_graph_config config.json"
- Then run
cargo mirai
and inspect the outputgraph.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:
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!
@hermanventer Thank you for responding and fixing this, much appreciated! We'll check out the latest commit.