在 Android NDK 之中,看上去調用 connect、socket 函數是不會崩潰的,但這是否定的,它在特定的情況下存在必定的崩潰的問題。
但是這種情況放到MACOS、LINUX、WINDOWS都不會崩潰,而它崩潰的點出現在操作系統底層。
人們需要參考這兩個系統底層 C/C++ 文件實現及關聯源文件實現:
https://android.googlesource.com/platform/frameworks/base.git/+/android-4.2.2_r1/core/jni/AndroidRuntime.cpp
https://android.googlesource.com/platform/system/netd/+/master/client/FwmarkClient.cpp
崩潰(例程):
調用 socket 函數導致 SIGSEGV 段錯誤崩潰。
直接說重點:
Google 實現的NDK標準庫是經過特殊定制,這種問題出現在,“stackful” 協同程序之中調用它們,但是它們崩潰有幾個基本要素。
1、對于 socket 創建一個UDP/TCP文件描述符,在有棧協程之中100%崩潰。
2、對于 socket 創建的TCP文件描述符,在有棧協程之中 send、recv、recvmsg、sendmsg 函數不會崩潰。?
同理UDP的套接字,在創建時會崩潰,但調用 sendto、recvform 不會崩潰,但它并不僅僅只是在有棧協程之中會崩潰。
準確的說是,只要當前 “線程棧” 無法回溯?Fwmark 都會導致崩潰,在NDK之中創建的線程都是在 LINUX 基礎上,從 Fwmark 之中執行后在驅動調用,只是這類常見于應用在協程。
解決辦法,在可以回溯 Fwmark 的線程上面執行,socket、connect 函數,在驅動該自定義線程棧上面。
通常在 C/C++ 之中,那些線程可以確定為?Fwmark 驅動可回溯線程?
1、main 線程(若為進程)
2、std::thread 線程(NDK在標準庫之中魔改過)