android - 无法弄清楚为什么此代码在发送数据包数据时会导致 SIGSEGV

标签 android c++ c sockets networking

我正在使用 POSIX 套接字在 Android 上编写一些网络代码,但是当我调用 Sento 时,我收到了一个奇怪的 SIGSEGV(信号 11,代码 1)。我已经使用墓碑跟踪来确定它是哪一行,但坦率地说,我看不出它有什么问题。

在此特定 fragment 之前,对 i_Socket 和 i_Server 的引用已成功。我还应该提到这些字符串来自 Mono/Unity 的编码字符串。

// Set client informaion
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; // We don't care IPv4 or IPv6
hints.ai_socktype = SOCK_DGRAM; // UDP Datagram packets

// Resolve server domain name
int res = getaddrinfo(server, TFTP_PORT, &hints, &i_ServerList);

// Check if we got a valid result
if (res != 0) {
    // Report error
    if (res == EAI_SYSTEM) 
        StreamingVideoPluginError("getaddrinfo");
    else {
        std::stringstream str;
        str << "error in getaddrinfo: " << gai_strerror(res);
    }
    return 1; // No such host
}

// Loop through all entries and bind to the first one we can
bool didBind = false;
for (auto i_Server = i_ServerList; i_Server != nullptr; i_Server = i_Server->ai_next) {
    // Try create the socket
    if ((i_Socket = socket(i_Server->ai_family, i_Server->ai_socktype, i_Server->ai_protocol)) == -1) {
        // Display error
        StreamingVideoPluginError("client: socket creation failure");
        i_Socket = -1; // Reassert invalid socket
        continue;
    }
    else {
        // Binded a socket
        didBind = true;
        break;
    }
}

// Check if we could bind to a server
if (!didBind) {
    StreamingVideoPluginError("Failed to bind to a server.");
    return 2;
}

// Set socket options
struct timeval tv;
memset(&tv, 0, sizeof (struct timeval));
tv.tv_sec = 5; // 5 second timeout
if (setsockopt(i_Socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv) == -1)
{
    std::stringstream str;
    str << "client: could not set timeout. errno =" << errno;
    StreamingVideoPluginError(str.str());
    return 3;
}


// Make the initial TFTP request
char tftp_buffer[512 + 4];
// Set the opcode to be read request
int packetLength = 0;
tftp_buffer[0] = 0;                   
tftp_buffer[1] = TFTP_RRQ;
packetLength = 2;


// Place filename
memcpy(&tftp_buffer[packetLength],tftpFileName, strlen(tftpFileName));
packetLength += strlen(tftpFileName);
tftp_buffer[packetLength] = 0; packetLength++;

// Set transfer type to be octet
memcpy(&tftp_buffer[packetLength], TRANSFER_TYPE, strlen(TRANSFER_TYPE));
packetLength += strlen(TRANSFER_TYPE);
tftp_buffer[packetLength] = 0; packetLength++;

std::stringstream str;
str << "Value of packetLength =" << packetLength;
StreamingVideoPluginLog(str.str());



// Send the TFTP request
if (sendto(i_Socket, tftp_buffer, packetLength, 0, i_Server->ai_addr, i_Server->ai_addrlen) == -1) {
    // Could not send TFTP request
    StreamingVideoPluginError("client: could not send tftp request.");

    return 4;
}

这是 NDK-Stack 的输出

signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000018
Stack frame #00  pc 0001e544  /data/app-lib/com.imersia-2/PLUGINNAME.so (ImersiaTftpDa
taSource::Init(char const*, char const*)+1292)
Stack frame #01  pc 0001d428  /data/app-lib/NOPENOPENOPE-2/PLUGINNAME.so (std::priv::_S
TLP_alloc_proxy<char*, char, std::allocator<char> >::~_STLP_alloc_proxy()+16)

addr2line 责备

C:/NVPACK/android-ndk-r10/sources/cxx-stl/stlport/stlport/stl/_alloc.h:472

最佳答案

发现问题了。我不小心在 for 循环内重新绑定(bind) i_Server 。

for (auto i_Server = i_ServerList; i_Server != nullptr; i_Server = i_Server->ai_next) {

应该是

for (i_Server = i_ServerList; i_Server != nullptr; i_Server = i_Server->ai_next) {

关于android - 无法弄清楚为什么此代码在发送数据包数据时会导致 SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24907366/

相关文章:

android - 如何在Android中创建动态Sqlite数据库

android - “R 无法解析为变量”- gen 文件夹为空

c - EXC_BAD_ACCESS,无法定位错误

c - 使用makefile编译时如何设置GDB?

c - 从单行读取多个数据

java - Android 应用程序导致 SIGSEGV,我该如何调试?

android - 在闪屏 Activity 期间进入全屏

c++ - 更改 ffmpeg 中的 mpeg ts pid 值

c# - Visual Studio 扩展 (VSIX/DLL) 到一个 exe

C++ 对象生命周期分析