I have an LD_PRELOAD program I am writing.
I do use unsafe code to intercept libc execv, and family of API to propagate itself across exec* and spawns libc calls of other processes to track file system access across a very large build
I just verified that the execv intercept propagation works just fine across a very large 3 hour build.
I then added some simple code to open tracker.file in append mode in RUST where I will eventually be writing tracking data. For starters it only writes process start up data in the library constructor annd everything works fine again across the 3 hour build.
As a last step i addd some tracking data writes from within the intercepted exec* family of calls to the already open tracker.file.
And now I am seeing tracebacks.
<0000929> Partitioner: Partitioner: Exception: Invalid component metadata files
<0000929> Partitioner: manageability/edmlib/comp-mdata.pl:
<0000929> Partitioner: - thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err`
value: Os { code: 9, kind: Other, message: "Bad file descriptor" }', src/tracker.rs:255:118
<0000929> Partitioner: stack backtrace:
<0000929> Partitioner: 0: rust_begin_unwind
<0000929> Partitioner: at /rustc/7e6d6e5f535321c2223f044caba16f97b825009c/library/std/src/
panicking.rs:475
<0000929> Partitioner: 1: core::panicking::panic_fmt
<0000929> Partitioner: at /rustc/7e6d6e5f535321c2223f044caba16f97b825009c/library/core/src
/panicking.rs:85
<0000929> Partitioner: 2: core::option::expect_none_failed
<0000929> Partitioner: at /rustc/7e6d6e5f535321c2223f044caba16f97b825009c/library/core/src
/option.rs:1219
<0000929> Partitioner: 3: core::result::Result<T,E>::unwrap
<0000929> Partitioner: at /rustc/7e6d6e5f535321c2223f044caba16f97b825009c/library/core/src
/result.rs:1005
<0000929> Partitioner: 4: wisktrack::tracker::Tracker::report
<0000929> Partitioner: at /ws/sarvi-sjc/wisktrack/src/tracker.rs:255
<0000929> Partitioner: 5: wisktrack::tracker::Tracker::reportexecv
<0000929> Partitioner: at /ws/sarvi-sjc/wisktrack/src/tracker.rs:373
<0000929> Partitioner: 6: wisktrack::my_execv
<0000929> Partitioner: at /ws/sarvi-sjc/wisktrack/src/lib.rs:162
<0000929> Partitioner: 7: wisktrack::execv::{{closure}}
<0000929> Partitioner: at /ws/sarvi-sjc/redhook/src/ld_preload.rs:67
........
Individual simple test cases of execv itnerceptions works fine.
But in larger multi threaded multi process builds only the execv intercept stack traces with "Bad File Descriptor" errors.
Question 1. If I all I am doing is open a file in append mode, holding the file object as a global lazy_static and writing to it possibly from multiple threads, are there possibilities of "Bad File Descriptor" expected. As in RUST, can I expect to handle when file descriptors are destoyed?
In my case I just happened to be calling the tracker.file writes from unsafe C extern code that overrides libc API.
Question 2: Does rust offer any tools to help debug such cases, like tracking when file objects are destroyed. In this case, it looks like my file object is fine but the file descriptor it is holding is deleted. How is that possible. In my case I dot have any code that formall deletes/closes the file object. It is held as a lazy_ static, so the only way it get deleted is at the end of the program.
Question 3: In this case, considering this happens only when writinng to tracker.file from within the exec* family of functions I suspect what is happening is that process/program that could be any program not writte in RUST is forking and execing. What is the impact of forking on open RUST file objects and their file descriptors. the real exec hasnt happenned, yet, he traceback before it reaches the real exec