Skip to content

Commit c36fa4d

Browse files
committed
Compare thin pointers to find the connection
Connection is a trait, so "*const Connection" is a fat pointer (128 bits, 64 bits pointing to the instance, 64 bits pointing to the vtable). For some reason (a bug?), in Router::remove(), the connection passed as argument has a vtable different from the (same) connection stored in the "connections" field. This has the unexpected consequence that for some x and y: println!("{:p} == {:p} ? {}", x, y, ptr::eq(x, y)); prints: 0x7f87a8c3a618 == 0x7f87a8c3a618 ? false Thus, the connection to remove was not found, leading to the panic "Removing an unknown connection". Instead, compare only the data part, by casting the fat pointers to thin pointers. See <#61 (comment)> Thanks to mbrubeck on IRC freenode/##rust, who helped a lot to understand the issue.
1 parent 235ce78 commit c36fa4d

File tree

2 files changed

+11
-2
lines changed

2 files changed

+11
-2
lines changed

relay-rust/src/relay/binary.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,12 @@ pub fn to_string(data: &[u8]) -> String {
3535
}
3636
s
3737
}
38+
39+
// only compare the data part for fat pointers (ignore the vtable part)
40+
// for some (buggy) reason, the vtable part may be different even if the data reference the same
41+
// object
42+
// See <https://github.com/Genymobile/gnirehtet/issues/61#issuecomment-370933770>
43+
pub fn ptr_data_eq<T: ?Sized>(lhs: *const T, rhs: *const T) -> bool {
44+
// cast to thin pointers to ignore the vtable part
45+
lhs as *const () == rhs as *const ()
46+
}

relay-rust/src/relay/router.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ impl Router {
150150
let index = self.connections
151151
.iter()
152152
.position(|item| {
153-
// compare pointers to find the connection to remove
154-
ptr::eq(connection, item.as_ptr())
153+
// compare (thin) pointers to find the connection to remove
154+
binary::ptr_data_eq(connection, item.as_ptr())
155155
})
156156
.expect("Removing an unknown connection");
157157
debug!(

0 commit comments

Comments
 (0)