xd009642/tarpaulin

Fails to build on x86

kpcyrd opened this issue · 3 comments

Describe the bug

Opening this as a tracking issue, related to #1467 and https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/59413.

To Reproduce

Simply build for 32bit x86:

error[E0308]: mismatched types
   --> src/event_log.rs:126:43
    |
126 | ...                   event.child = get_event_data(*pid).ok();
    |                       -----------   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i64>`, found `Option<i32>`
    |                       |
    |                       expected due to the type of this binding
    |
    = note: expected enum `std::option::Option<i64>`
               found enum `std::option::Option<i32>`
error[E0308]: mismatched types
   --> src/event_log.rs:132:43
    |
132 | ...                   event.child = get_event_data(*pid).ok();
    |                       -----------   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i64>`, found `Option<i32>`
    |                       |
    |                       expected due to the type of this binding
    |
    = note: expected enum `std::option::Option<i64>`
               found enum `std::option::Option<i32>`
error[E0308]: mismatched types
   --> src/event_log.rs:138:43
    |
138 | ...                   event.child = get_event_data(*pid).ok();
    |                       -----------   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i64>`, found `Option<i32>`
    |                       |
    |                       expected due to the type of this binding
    |
    = note: expected enum `std::option::Option<i64>`
               found enum `std::option::Option<i32>`
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:59:34
   |
59 |         let mut intdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 & i64`
  --> src/process_handling/breakpoint.rs:59:32
   |
59 |         let mut intdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                ^ no implementation for `i32 & i64`
   |
   = help: the trait `std::ops::BitAnd<i64>` is not implemented for `i32`
   = help: the following other types implement trait `std::ops::BitAnd<Rhs>`:
             <i32 as std::ops::BitAnd>
             <i32 as std::ops::BitAnd<&i32>>
             <&'a i32 as std::ops::BitAnd<i32>>
             <&i32 as std::ops::BitAnd<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:60:20
   |
60 |         intdata |= (INT << self.shift) as i64;
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 |= i64`
  --> src/process_handling/breakpoint.rs:60:17
   |
60 |         intdata |= (INT << self.shift) as i64;
   |                 ^^ no implementation for `i32 |= i64`
   |
   = help: the trait `BitOrAssign<i64>` is not implemented for `i32`
   = help: the following other types implement trait `BitOrAssign<Rhs>`:
             <i32 as BitOrAssign>
             <i32 as BitOrAssign<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:64:59
   |
64 |             write_to_address(pid, self.aligned_address(), intdata)
   |             ----------------                              ^^^^^^^ expected `i64`, found `i32`
   |             |
   |             arguments to this function are incorrect
   |
note: function defined here
  --> src/process_handling/ptrace_control.rs:42:8
   |
42 | pub fn write_to_address(pid: Pid, address: u64, data: i64) -> Result<()> {
   |        ^^^^^^^^^^^^^^^^                         ---------
help: you can convert an `i32` to an `i64`
   |
64 |             write_to_address(pid, self.aligned_address(), intdata.into())
   |                                                                  +++++++
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:71:34
   |
71 |         let mut orgdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 & i64`
  --> src/process_handling/breakpoint.rs:71:32
   |
71 |         let mut orgdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                ^ no implementation for `i32 & i64`
   |
   = help: the trait `std::ops::BitAnd<i64>` is not implemented for `i32`
   = help: the following other types implement trait `std::ops::BitAnd<Rhs>`:
             <i32 as std::ops::BitAnd>
             <i32 as std::ops::BitAnd<&i32>>
             <&'a i32 as std::ops::BitAnd<i32>>
             <&i32 as std::ops::BitAnd<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:72:20
   |
72 |         orgdata |= i64::from(self.data) << self.shift;
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 |= i64`
  --> src/process_handling/breakpoint.rs:72:17
   |
72 |         orgdata |= i64::from(self.data) << self.shift;
   |                 ^^ no implementation for `i32 |= i64`
   |
   = help: the trait `BitOrAssign<i64>` is not implemented for `i32`
   = help: the following other types implement trait `BitOrAssign<Rhs>`:
             <i32 as BitOrAssign>
             <i32 as BitOrAssign<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:73:55
   |
73 |         write_to_address(pid, self.aligned_address(), orgdata)
   |         ----------------                              ^^^^^^^ expected `i64`, found `i32`
   |         |
   |         arguments to this function are incorrect
   |
note: function defined here
  --> src/process_handling/ptrace_control.rs:42:8
   |
42 | pub fn write_to_address(pid: Pid, address: u64, data: i64) -> Result<()> {
   |        ^^^^^^^^^^^^^^^^                         ---------
help: you can convert an `i32` to an `i64`
   |
73 |         write_to_address(pid, self.aligned_address(), orgdata.into())
   |                                                              +++++++
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `cargo-tarpaulin` (lib) due to 13 previous errors
warning: build failed, waiting for other jobs to finish...

I didn't get around to fully port this yet, but one required change seems to be:

diff --git a/Cargo.toml b/Cargo.toml
index db80d35..f1d65e2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -56,7 +56,7 @@ walkdir = "2.4.0"
 glob = "0.3.1"
 enum-display = "0.1.3"
 
-[target.'cfg(all(target_os = "linux", target_arch = "x86_64"))'.dependencies]
+[target.'cfg(all(target_os = "linux", any(target_arch = "x86_64", target_arch = "x86")))'.dependencies]
 libc = "0.2.94"
 nix = {version = "0.27.1", default-features = false, features = ["sched", "signal", "ptrace", "personality"]}
 procfs = "0.16"

This wasn't caught earlier because tests for x86 secretly run on x86_64, see #1467.

Expected behavior

Builds on x86.

I merged in that change with #1521 as it seems to be the only one needed (had a brief look at ptrace code to make sure registers etc look correct). I still haven't got CI to behave and needing OpenSSL versions for the target might complicate it further so fixing the CI is still a TODO

Sorry for not getting back to this sooner, I'm still getting some errors with 0.30.0 on x86 musl:

error[E0308]: mismatched types
   --> src/event_log.rs:126:43
    |
126 | ...                   event.child = get_event_data(*pid).ok();
    |                       -----------   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i64>`, found `Option<i32>`
    |                       |
    |                       expected due to the type of this binding
    |
    = note: expected enum `std::option::Option<i64>`
               found enum `std::option::Option<i32>`
error[E0308]: mismatched types
   --> src/event_log.rs:132:43
    |
132 | ...                   event.child = get_event_data(*pid).ok();
    |                       -----------   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i64>`, found `Option<i32>`
    |                       |
    |                       expected due to the type of this binding
    |
    = note: expected enum `std::option::Option<i64>`
               found enum `std::option::Option<i32>`
error[E0308]: mismatched types
   --> src/event_log.rs:138:43
    |
138 | ...                   event.child = get_event_data(*pid).ok();
    |                       -----------   ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<i64>`, found `Option<i32>`
    |                       |
    |                       expected due to the type of this binding
    |
    = note: expected enum `std::option::Option<i64>`
               found enum `std::option::Option<i32>`
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:59:34
   |
59 |         let mut intdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 & i64`
  --> src/process_handling/breakpoint.rs:59:32
   |
59 |         let mut intdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                ^ no implementation for `i32 & i64`
   |
   = help: the trait `std::ops::BitAnd<i64>` is not implemented for `i32`
   = help: the following other types implement trait `std::ops::BitAnd<Rhs>`:
             <i32 as std::ops::BitAnd>
             <i32 as std::ops::BitAnd<&i32>>
             <&'a i32 as std::ops::BitAnd<i32>>
             <&i32 as std::ops::BitAnd<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:60:20
   |
60 |         intdata |= (INT << self.shift) as i64;
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 |= i64`
  --> src/process_handling/breakpoint.rs:60:17
   |
60 |         intdata |= (INT << self.shift) as i64;
   |                 ^^ no implementation for `i32 |= i64`
   |
   = help: the trait `std::ops::BitOrAssign<i64>` is not implemented for `i32`
   = help: the following other types implement trait `std::ops::BitOrAssign<Rhs>`:
             <i32 as std::ops::BitOrAssign>
             <i32 as std::ops::BitOrAssign<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:64:59
   |
64 |             write_to_address(pid, self.aligned_address(), intdata)
   |             ----------------                              ^^^^^^^ expected `i64`, found `i32`
   |             |
   |             arguments to this function are incorrect
   |
note: function defined here
  --> src/process_handling/ptrace_control.rs:42:8
   |
42 | pub fn write_to_address(pid: Pid, address: u64, data: i64) -> Result<()> {
   |        ^^^^^^^^^^^^^^^^                         ---------
help: you can convert an `i32` to an `i64`
   |
64 |             write_to_address(pid, self.aligned_address(), intdata.into())
   |                                                                  +++++++
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:71:34
   |
71 |         let mut orgdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 & i64`
  --> src/process_handling/breakpoint.rs:71:32
   |
71 |         let mut orgdata = data & (!(0xFFu64 << self.shift) as i64);
   |                                ^ no implementation for `i32 & i64`
   |
   = help: the trait `std::ops::BitAnd<i64>` is not implemented for `i32`
   = help: the following other types implement trait `std::ops::BitAnd<Rhs>`:
             <i32 as std::ops::BitAnd>
             <i32 as std::ops::BitAnd<&i32>>
             <&'a i32 as std::ops::BitAnd<i32>>
             <&i32 as std::ops::BitAnd<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:72:20
   |
72 |         orgdata |= i64::from(self.data) << self.shift;
   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `i64`
error[E0277]: no implementation for `i32 |= i64`
  --> src/process_handling/breakpoint.rs:72:17
   |
72 |         orgdata |= i64::from(self.data) << self.shift;
   |                 ^^ no implementation for `i32 |= i64`
   |
   = help: the trait `std::ops::BitOrAssign<i64>` is not implemented for `i32`
   = help: the following other types implement trait `std::ops::BitOrAssign<Rhs>`:
             <i32 as std::ops::BitOrAssign>
             <i32 as std::ops::BitOrAssign<&i32>>
error[E0308]: mismatched types
  --> src/process_handling/breakpoint.rs:73:55
   |
73 |         write_to_address(pid, self.aligned_address(), orgdata)
   |         ----------------                              ^^^^^^^ expected `i64`, found `i32`
   |         |
   |         arguments to this function are incorrect
   |
note: function defined here
  --> src/process_handling/ptrace_control.rs:42:8
   |
42 | pub fn write_to_address(pid: Pid, address: u64, data: i64) -> Result<()> {
   |        ^^^^^^^^^^^^^^^^                         ---------
help: you can convert an `i32` to an `i64`
   |
73 |         write_to_address(pid, self.aligned_address(), orgdata.into())
   |                                                              +++++++
Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `cargo-tarpaulin` (lib) due to 13 previous errors
warning: build failed, waiting for other jobs to finish...

https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/65625

So I think the solution is a bit more liberal sprinkling of c_long and c_ulong just to keep the types as matched as possible. I tried to build it for i686 myself but unfortunately openssl doesn't like that and I haven't yet figured out a nice way to build it and check it builds myself.

I have pushed something to the fix/x86-build branch though if you want to try that out and see if it works - that might get things moving quicker