在 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在标准库之中魔改过)