首页 > 解决方案 > gethostbyname() 和 getlogin_r() 等函数在远程调试时停止运行时执行

问题描述

我目前正在使用Visual Studio Remote Development,开发一个应该在 Linux 上运行但在 Windows 上开发的应用程序。作为远程机器,我使用的是 WSL2 Ubuntu 机器,它与 VS 开发环境运行在同一系统上。

我有以下代码片段,每次我运行或调试它时都会停止。这段代码很像 C,但是我使用 g++ 编译它,因为它是一个更大的 C++ 项目的一部分:

struct passwd* pw { getpwuid(geteuid()) }; // execution stops here, program crashes

// [...] if I remove the above part, execution continues:

struct hostent* host { nullptr };
char hostname[64];
strncpy(hostname, "unknown", 64);
hostname[63]='\0';

gethostname(hostname, 64);

host = gethostbyname(hostname); // execution stops here, program crashes

Linux 控制台输出:

5675-exec-next
Stopped due to shared library event (no libraries added or removed)
Stopped due to shared library event:
  Inferior loaded /lib/x86_64-linux-gnu/libnss_files.so.2
5676-break-info 2
5677-break-info 4
5678-break-info 5
Loaded '/lib/x86_64-linux-gnu/libnss_files.so.2'. Symbols loaded.
Stopped due to shared library event (no libraries added or removed)
Stopped due to shared library event:
  Inferior loaded /usr/lib/x86_64-linux-gnu/gconv/UTF-16.so
5680-break-info 2
5681-break-info 4
5682-break-info 5
Loaded '/usr/lib/x86_64-linux-gnu/gconv/UTF-16.so'. Symbols loaded.
Stopped due to shared library event (no libraries added or removed)
Stopped due to shared library event:
  Inferior loaded /opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1
    /lib/x86_64-linux-gnu/librt.so.1
    /lib/x86_64-linux-gnu/libodbcinst.so.2
    /lib/x86_64-linux-gnu/libcrypto.so.1.0.2
    /lib/x86_64-linux-gnu/libkrb5.so.3
    /lib/x86_64-linux-gnu/libgssapi_krb5.so.2
    /lib/x86_64-linux-gnu/libssl.so.1.0.2
    /lib/x86_64-linux-gnu/libuuid.so.1
    /lib/x86_64-linux-gnu/libk5crypto.so.3
    /lib/x86_64-linux-gnu/libcom_err.so.2
    /lib/x86_64-linux-gnu/libkrb5support.so.0
    /lib/x86_64-linux-gnu/libkeyutils.so.1
    /lib/x86_64-linux-gnu/libresolv.so.2
5684-break-info 2
5685-break-info 4
5686-break-info 5
Loaded '/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.3.so.1.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/librt.so.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libodbcinst.so.2'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libcrypto.so.1.0.2'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libkrb5.so.3'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libgssapi_krb5.so.2'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libssl.so.1.0.2'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libuuid.so.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libk5crypto.so.3'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libcom_err.so.2'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libkrb5support.so.0'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libkeyutils.so.1'. Symbols loaded.
Loaded '/lib/x86_64-linux-gnu/libresolv.so.2'. Symbols loaded.

这里的问题是我没有看到任何简单的错误或中止消息,也没有以任何方式提供调试器输出。

我在 WSL 中设置了一个简单的测试文件(其中可能有一些不必要的包含,对此感到抱歉)来测试该功能是否基本有效:

#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>

int main()
{
    struct hostent* hp = gethostbyname("MY-HOSTNAME\0");

    if (hp == nullptr) {
        printf("failed.\n");
    }
    else {
        printf("%s = ", hp->h_name);
        int i = 0;

        while (hp->h_addr_list[i] != nullptr) {
            printf("%s", inet_ntoa(*(struct in_addr*)(hp->h_addr_list[i])));
            ++i;
        }

        printf("\n");
    }

    return 0;
}

输出:MY-HOSTNAME = 127.0.0.1

所以基本上该功能似乎在子系统内部工作。

getlogin_r(hostname)使用or时也会出现同样的问题getpwuid(geteuid())

初始化调试器(我设置为)时,VS远程调试器是否有可能加载错误的库gdb

标签: c++clinuxgcc

解决方案


推荐阅读