ROKID Staton2 ADB Crash 问题解决记录

很奇怪啊,adb 在 Rokid 上崩了

报错只有这个信息

fdsan: failed to exchange ownership of file descriptor: fd 11 is owned by unique_fd 0x76e2500458, was expected to be unowned

我个人对于这种有着及大量 C/C++ 代码的程序出现问题,基本就是用很土的方法

二分日志法

就是从 main 函数的开始和结尾打上一个日志,然后在中间的位置打上一个日志

看下崩溃的日志是在哪个区间,然后逐渐缩小范围

看一下加上日志后 crash 的输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
Launching lib/main.dart on RG station2 in debug mode...
✓ Built build/app/outputs/flutter-apk/app-debug.apk
***
I/flutter (12482): [I] ADB polling error : Exception: * daemon not running; starting now at tcp:5037
I/flutter (12482): [I] * daemon started successfully
I/flutter (12482): [I] error: protocol fault (couldn't read status): Connection reset by peer
I/flutter (12482): [I]
D/ProfileInstaller(12482): Installing profile for com.nightmare.remote
I/flutter (12482): [I] ADB polling error : Exception: * daemon not running; starting now at tcp:5037
I/flutter (12482): [I] * daemon started successfully
I/flutter (12482): [I] error: protocol fault (couldn't read status): Connection reset by peer
I/flutter (12482): [I]
I/flutter (12482): [I] ADB polling error : Exception: * daemon not running; starting now at tcp:5037
I/flutter (12482): [I] ADB server didn't ACK
I/flutter (12482): [I] Full server startup log: /data/data/com.nightmare.remote/files/usr/bin/adb.10132.log
I/flutter (12482): [I] Server had pid: 12598
I/flutter (12482): [I] --- adb starting (pid 12598) ---
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:63 Android Debug Bridge version 1.0.41
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:63 Version 35.0.3-3.35.001-20241010-130201
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:63 Installed as /data/app/~~C4RvqyAAdViMpMm8iMumHA==/com.nightmare.remote-D61hRw9Vp3k2uSteY-mqyQ==/lib/arm64/libadb.so
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:63 Running on Linux 5.10.198-qki-consolidate-android12-9-gd70a73cbc90f (aarch64)
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:63
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:132 setup_daemon_logging invoke done atexit will be called
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:136 init_reconnect_handler will called
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:140 init_reconnect_handler invoke done
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb : main.cpp:143 init_mdns_transport_discovery invoke
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : task_runner.cpp:57 tasks_.emplace called now + delay -> 3369119 ms since epoch
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : main.cpp:145 init_mdns_transport_discovery invoke done
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : main.cpp:152 usb_init invoke
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12600 I adb : fdevent.cpp:276 9.1
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12600 I adb : fdevent.cpp:211 8.1.xx
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : main.cpp:154 usb_init invoke done
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : main.cpp:161 local_init invoke
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : main.cpp:163 local_init invoke done
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 E adb : usb_linux.cpp:143 find_usb_device bus_name-> /dev/bus/usb/003
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> .
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> ..
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> 001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : auth.cpp:419 adb_auth_init...
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:170 unix_open failed d_name-> 001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 E adb : usb_linux.cpp:143 find_usb_device bus_name-> /dev/bus/usb/002
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> .
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> ..
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> 002
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:170 unix_open failed d_name-> 002
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> 001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:170 unix_open failed d_name-> 001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 E adb : usb_linux.cpp:143 find_usb_device bus_name-> /dev/bus/usb/001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> .
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> ..
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:149 find_usb_device d_name-> 001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12601 I adb : usb_linux.cpp:170 unix_open failed d_name-> 001
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12602 I adb : fdevent.cpp:276 9.1
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12602 I adb : fdevent.cpp:211 8.1.xx
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : auth.cpp:152 loaded new key from '/data/data/com.nightmare.remote/files/usr/bin/.android/adbkey' with fingerprint 1472BA4C908DFCB4B03AB6912355A3B83BBF5EF322142123E9D2D6C51CA55536
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : auth.cpp:391 adb_auth_inotify_init...
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : auth.cpp:393 1...
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : auth.cpp:395 2... infd = 8
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : auth.cpp:412 3
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : auth.cpp:436 4...
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : main.cpp:185 5
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : main.cpp:200 6
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : main.cpp:243 7
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : main.cpp:259 8
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:281 8.1
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent_epoll.cpp:112 8.1.1
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent_epoll.cpp:118 8.1.2
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent_epoll.cpp:125 8.1.3
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent_epoll.cpp:146 8.1.4
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent_epoll.cpp:178 8.1.5
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent_epoll.cpp:197 8.1.6
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:155 8.1.6.1
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:157 8.1.6.2(fdevent 0: fd 5 R) got events 1
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:161 8.1.6.3
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:166 8.1.6.4
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:175 8.1.6.4.1
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:180 8.1.6.4.2
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:186 8.1.6.4.4
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:188 8.1.6.4.5
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:190 8.1.6.4.6
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : fdevent.cpp:207 Executing fn
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : task_runner.cpp:120 waitable_task called
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : task_runner.cpp:113 task called
I/flutter (12482): [I] fdsan: failed to exchange ownership of file descriptor: fd 7 is owned by unique_fd 0x7959de91b8, was expected to be unowned

起初我只定位到崩溃的地方在 fdevent.cpp:207,也就是还没有这两行日志

1
2
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb     : task_runner.cpp:120 waitable_task called
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : task_runner.cpp:113 task called

fdevent.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void fdevent_context::Run(std::function<void()> fn) {
auto wrapped_fn = [fn]() {
LOG(INFO) << "Executing fn";
// fdevent.cpp:207
fn();
};
{
LOG(INFO) << "8.1.xx ";
std::lock_guard<std::mutex> lock(run_queue_mutex_);
run_queue_.push_back(std::move(wrapped_fn));
}

Interrupt();
}

207 行调用了一个回调函数,姑且这么称它吧,这种就棘手一点,因为你不知道回调函数是谁

看下崩溃的链路,从入口函数到崩溃的整条链路如下

adb_server_main -> fdevent_loop -> fdevent_get_ambient()->Loop()
-> fdevent_context::HandleEvents -> FlushRunQueue

FlushRunQueue 函数如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

void fdevent_context::FlushRunQueue() {
// We need to be careful around reentrancy here, since a function we call can queue up another
// function.

LOG(INFO) << "8.1.6.4.1";
while (true) {
std::function<void()> fn;
{
std::lock_guard<std::mutex> lock(this->run_queue_mutex_);
LOG(INFO) << "8.1.6.4.2";
if (this->run_queue_.empty()) {
LOG(INFO) << "8.1.6.4.3";
break;
}
fn = std::move(this->run_queue_.front());
LOG(INFO) << "8.1.6.4.4";
this->run_queue_.pop_front();
LOG(INFO) << "8.1.6.4.5";
}
LOG(INFO) << "8.1.6.4.6";
fn();
LOG(INFO) << "8.1.6.4.7";
}
LOG(INFO) << "8.1.6.10";
}

看起来像是一个执行队列里面的任务的函数

而任务的注入是 fdevent_run_on_looper -> fdevent_get_ambient()->Run(std::move(fn))

所以这个时候的任务就是找到是哪个函数注入的这个任务(二分日志)

执行 fn 的时候崩了,是很难找打是哪儿注入的函数崩的,这个时候只有全局搜索 fdevent_run_on_looper 的调用,然后加日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void fdevent_context::Run(std::function<void()> fn) {
auto wrapped_fn = [fn]() {
LOG(INFO) << "Executing fn";
fn();
};
{
LOG(INFO) << "8.1.xx ";
std::lock_guard<std::mutex> lock(run_queue_mutex_);
run_queue_.push_back(std::move(wrapped_fn));
}

Interrupt();
}

void fdevent_run_on_looper(std::function<void()> fn) {
LOG(INFO) << "9.1";
fdevent_get_ambient()->Run(std::move(fn));
}

于是就有了这两行日志

1
2
3
4
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb     : task_runner.cpp:120 waitable_task called
I/flutter (12482): [I] 10-27 13:45:19.842 12598 12598 I adb : task_runner.cpp:113 task called
I/flutter (12482): [I] fdsan: failed to exchange ownership of file descriptor: fd 7 is owned by unique_fd 0x7959de91b8, was
expected to be unowned

最后崩溃函数是 task ,不难发现,无论是这个 task_runner 还是 event_poll ,都是 Event Loop,事件循环

也可称为生产消费模型?比较经典的事件队列,只要找到注入的地方就行

发现是 task_runner.cpp

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void AdbOspTaskRunner::TaskExecutorWorker() {
// ***
CHECK(!running_tasks.empty());
std::packaged_task<int()> waitable_task([&] {
for (Task& task : running_tasks) {
// task_runner.cpp:113
LOG(INFO) << "task called";
task();
}
return 0;
});

fdevent_run_on_looper([&]() {
// task_runner.cpp:120
LOG(INFO) << "waitable_task called";
waitable_task();
});
// ***

fdevent_run_on_looper -> waitable_task -> task

而这个 task 又是一个任务队列,又得找是哪儿注入的 task,执行的时候崩掉的

所以找注入 task 的地方的调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void AdbOspTaskRunner::PostPackagedTask(Task task) {
PostPackagedTaskWithDelay(std::move(task), openscreen::Clock::duration::zero());
}

void AdbOspTaskRunner::PostPackagedTaskWithDelay(Task task, Clock::duration delay) {
auto now = std::chrono::steady_clock::now();
auto target_time = now + delay;
{
std::lock_guard<std::mutex> lock(mutex_);
auto target_time_ms = std::chrono::duration_cast<std::chrono::milliseconds>(target_time.time_since_epoch()).count();
LOG(INFO) << "tasks_.emplace called now + delay -> " << target_time_ms << " ms since epoch";
tasks_.emplace(now + delay, std::move(task));
}
cv_.notify_one();
}

仍然二分日志找调用

根据日志和代码

1
2
3
I/flutter (12482): [I] 10-27 13:45:19.840 12598 12598 I adb     : main.cpp:143 init_mdns_transport_discovery invoke 
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : task_runner.cpp:57 tasks_.emplace called now + delay -> 3369119 ms since epoch
I/flutter (12482): [I] 10-27 13:45:19.841 12598 12598 I adb : main.cpp:145 init_mdns_transport_discovery invoke done
1
2
3
4
5
6
7
8
int adb_server_main(/**/) {
/**/
if (!getenv("ADB_MDNS") || strcmp(getenv("ADB_MDNS"), "0") != 0) {
LOG(INFO) << "init_mdns_transport_discovery invoke ";
init_mdns_transport_discovery();
LOG(INFO) << "init_mdns_transport_discovery invoke done";
}
/**/

位于 init_mdns_transport_discovery() 函数中

具体不知道什么原因这个函数崩了,但 adb 的 mdns 在 rokid 上本来也没用上

根据源代码,定义一个环境变量 ADB_MDNS=0 就可以关闭这个功能

OVER

作者

梦魇兽

发布于

2024-10-27

更新于

2024-10-27

许可协议

评论