Skip to content

Commit 707c19e

Browse files
committed
add vec_push_mem_addr_change_cause_ffi_fail
1 parent fe7670b commit 707c19e

File tree

6 files changed

+59
-4
lines changed

6 files changed

+59
-4
lines changed

2022/02/wordle.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ answer: a,o,t is correct position, answer not contains b and r
5656

5757
## 4th guess
5858

59-
```
59+
```rust
6060
#[test]
6161
fn _4th_guess() {
6262
let start = std::time::Instant::now();

2023/07/rust_atomic_and_lock.md

+15
Original file line numberDiff line numberDiff line change
@@ -435,3 +435,18 @@ hazard pointers 类似引用计数,适用于读多写少场合
435435
## parking_lot's deadlock_detection feature
436436

437437
tokio 开 parking_lot feature, 然后 parking_lot 再开死锁检测就能检测死锁?
438+
439+
```rust
440+
use parking_lot::RwLock;
441+
let t = std::thread::spawn(|| {
442+
let x = RwLock::new(1);
443+
let r = x.read();
444+
let w = x.write();
445+
});
446+
unsafe { libc::sleep(1); }
447+
let dead_locks = parking_lot::deadlock::check_deadlock();
448+
dbg!(dead_locks[0][0].backtrace());
449+
t.join().unwrap();
450+
```
451+
452+
确实能检测出死锁的线程个数,但是 backtrace 上找不到自己的代码
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# [Vec::push FFI 内存错误](/2023/08/vec_push_mem_addr_change_cause_ffi_fail.md)
2+
3+
这样一段绑定数据库查询结果 buffer 的 FFI 调用代码发生了内存错误,期望是查询结果为 NULL 的时候 val_is_null flag 会被数据库动态库设置成 -1,然而 val_is_null 这个值并没有改
4+
5+
```rust
6+
for i in 0..num_fields {
7+
let column = Column {
8+
val_buf: vec![0u8; size],
9+
val_is_null: 0,
10+
};
11+
KCIDefineByPos(
12+
column.val_buf.as_mut_ptr().cast(),
13+
i32::try_from(column.val_buf.len()).unwrap(),
14+
((&mut column.val_is_null) as *mut i16).cast(),
15+
)
16+
.err(err)?;
17+
columns.push(column);
18+
}
19+
```
20+
21+
怀疑跨函数 move Columns 会改变内存地址,然后打印了下确实 move 没有修改地址,而且 columns 是个 vector 本身就分配到堆上
22+
23+
于是我把 val_is_null 设置成 **static** 就解决了问题,遇到 NULL 查询结果能正常被修改成 -1
24+
25+
最终发现原来问题出自 Vec::push 后 val_is_null 的内存地址变了(从栈上变成堆上)
26+
27+
```rust
28+
let column = Column {
29+
val_buf: vec![0u8; size],
30+
val_is_null: 0,
31+
};
32+
dbg!(&column.val_is_null as *const i16 as usize);
33+
columns.push(column);
34+
dbg!(&columns[i].val_is_null as *const i16 as usize);
35+
```
36+
37+
所以等 `columns.push(column);` 内存地址修改完后再把 val_is_null 的内存地址传给 FFI 调用就解决了

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
- [文章列表 - 吴翱翔的博客](/)
22
- [正在读的书](/books.md)
33
- **2023-08**
4+
- [Vec::push FFI 内存错误](/2023/08/vec_push_mem_addr_change_cause_ffi_fail.md)
45
- **2023-07**
56
- [Atomic Lock 读书笔记](/2023/07/rust_atomic_and_lock.md)
67
- [Mutex 源码实现](/2023/07/mutex_source_code_and_impl.md)

books.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
## 正在读的书
22

3-
- rust atomic and lock(ch6)
43
- computer science a programmer's perspective
54

65
## 已读
@@ -13,9 +12,12 @@
1312
- 為你自己學 Ruby on Rails
1413
- The Rust Programming Language(官方 the book 讲的太浅了)
1514
- Rust 编程之道
16-
- beginning linux programming(深入理解 gcc 动态库,与 APUE/TLPI 部分内容重叠)
15+
- beginning linux programming(与 APUE/TLPI 部分内容重叠)
16+
- Asynchronous Programming in Rust
1717
- Linux 高性能服务端编程
18+
- The Rustonomicon
1819
- 凤凰架构
20+
- Rust Atomics and Locks
1921

2022
## 已读非技术类书
2123

notes/unsafe_ffi/unsafe.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ variance一般可以分为三类:
1010
- 逆变(contravariant): 反过来Vec<Animal>是Vec<Cat>的子类型
1111
- 不变(invariant): 既不保持又不逆转关系 => Vec<Animal>和Vec<Cat>没有任何关系
1212

13-
Rust 只有生命周期体现了父子类型的概念
13+
Rust 只有生命周期体现了父子类型的概念(gpt 说 trait bound Sub: Super 也算子类型)
1414

1515
协变(绝大部分): 能传 'a 的也能传入 'static,生命周期短的父类型 'a 引用如果能传入函数,那么生命周期长的子类型 'static 引用也能传入
1616

0 commit comments

Comments
 (0)