Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 链接器抱怨可能未初始化变量(完全优化的构建选项)_C_Linux_Sockets_Gcc_Lto - Fatal编程技术网

C 链接器抱怨可能未初始化变量(完全优化的构建选项)

C 链接器抱怨可能未初始化变量(完全优化的构建选项),c,linux,sockets,gcc,lto,C,Linux,Sockets,Gcc,Lto,我正在编译一些以前编译过的代码(使用相同的选项),在一些不相关的更改之后,链接器开始查找可能未初始化的变量(我怀疑这些不相关的更改可能会干扰gcc的优化算法,并可能触发错误) 系统: debian 11(测试) linux 5.4.0-4-amd64 gcc 9.2.1(Debian 9.2.1-29) as 2.34 ld 2.34 我使用以下优化: -O3 -flto -fuse-linker-plugin -march=native -static 程序尝试设置tcp服务器,套接字可

我正在编译一些以前编译过的代码(使用相同的选项),在一些不相关的更改之后,链接器开始查找可能未初始化的变量(我怀疑这些不相关的更改可能会干扰gcc的优化算法,并可能触发错误)

系统:

  • debian 11(测试)
  • linux 5.4.0-4-amd64
  • gcc 9.2.1(Debian 9.2.1-29)
  • as 2.34
  • ld 2.34
我使用以下优化:

-O3 -flto -fuse-linker-plugin -march=native -static
程序尝试设置tcp服务器,套接字可能是未初始化的变量

libalx/base/socket/tcp/server.c

#include "libalx/base/socket/tcp/server.h"

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>

#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>


static
int     get_addrs       (const char *server_port, struct addrinfo **addrs);
static
int     set_server      (int sd, int *optval, struct addrinfo *ad, int backlog);
static
int     set_socket      (struct addrinfo *addrs, int backlog);


int     tcp_server_open     (const char *server_port, int backlog)
{
        int             sd;
        struct addrinfo *addrs;

        sd      = -1;
        if (get_addrs(server_port, &addrs))
                return  -1;
        sd      = set_socket(addrs, backlog);
        freeaddrinfo(addrs);

        if (sd < 0)
                return  -2;
        return  sd;
}


static
int     get_addrs       (const char *server_port, struct addrinfo **addrs)
{
        struct protoent *tcp;
        struct addrinfo hint = {0};

        tcp     = getprotobyname("tcp");
        if (!tcp)
                return  -1;
        hint.ai_family          = AF_UNSPEC;
        hint.ai_socktype        = SOCK_STREAM;
        hint.ai_protocol        = tcp->p_proto;
        hint.ai_flags           = AI_PASSIVE;
        if (getaddrinfo(NULL, server_port, &hint, addrs))
                return  -1;
        return  0;
}

static
int     set_socket      (struct addrinfo *addrs, int backlog)
{
        int     val;
        int     sock;

        sock    = -1;
        for (struct addrinfo *ad = addrs; ad; ad = ad->ai_next) {
                sock = socket(ad->ai_family, ad->ai_socktype, ad->ai_protocol);
                if (sock < 0)
                        continue;
                if (!set_server(sock, &val, ad, backlog))
                        break;
                close(sock);
                sock    = -1;
        }

        return  sock;
}

static
int     set_server      (int sd, int *optval, struct addrinfo *ad, int backlog)
{

        *optval = 1;
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, optval, sizeof(*optval)))
                return  -1;
        if (bind(sd, ad->ai_addr, ad->ai_addrlen))
                return  -1;
        if (listen(sd, backlog))
                return  -1;
        return  0;
}
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <unistd.h>

#include <linux/membarrier.h>

#define ALX_NO_PREFIX
#include <libalx/base/compiler/size.h>
#include <libalx/base/linux/membarrier.h>
#include <libalx/base/socket/tcp/server.h>


static  int             mb_cmd;
static  sig_atomic_t    sigterm;
static  int             tcp;


static
int     rob_init        (void);
static
int     rob_deinit      (void);
static
int     tcp_init        (void);
static
int     tcp_deinit      (void);

static
void    cam_session     (int cam);

static
int     mb_init         (void);
static
int     sigterm_init    (void);
static
void    sigterm_handler (int sig);


int     main            (void)
{
        int                     tcp;
        int                     cam;
        struct sockaddr_storage cam_addr = {0};
        socklen_t               cam_addr_len;
        int                     status;

        status  = 1;
        if (rob_init())
                goto out0;

        status++;
        cam_addr_len    = sizeof(cam_addr);
        do {
                cam = accept(tcp, (struct sockaddr *)&cam_addr, &cam_addr_len);
                if (cam < 0) {
                        goto retry;
                }

                cam_session(cam);
                close(cam);
        retry:
                asm volatile ("" : : : "memory");
        } while (!sigterm);

        status  = EXIT_SUCCESS;

        if (rob_deinit())
                status  += 32;
out0:
        fprintf(stderr, "rob: ERROR: main(): %i\n", status);

        return  status;
}


static
int     rob_init        (void)
{
        int     status;

        status  = -1;
        if (sigterm_init())
                goto err;
        status--;
        if (tcp_init())
                goto err;
        return  0;
err:
        fprintf(stderr, "rob: ERROR: rob_init(): %i\n", status);
        return  status;
}

static
int     rob_deinit      (void)
{
        int     status;

        status  = 0;
        if (tcp_deinit())
                status--;

        return  status;
}

static
int     tcp_init        (void)
{

        tcp     = -1;
        tcp     = tcp_server_open("23", 10);
        return  tcp < 0;
}

static
int     tcp_deinit      (void)
{
        return  close(tcp);
}

static
void    cam_session     (int cam)
{
        static  int i = 0;
        char    cam_data[BUFSIZ];
        ssize_t n;

        i++;
        while (true) {
                n = read(cam, cam_data, ARRAY_SIZE(cam_data) - 1);
                if (n < 0)
                        return;
                cam_data[n]     = 0;
                if (!n)
                        return;
                printf("%s\n", cam_data);
        }
}


static
int     mb_init         (void)
{
        static bool     done = false;
        int             cmd;

        if (done)
                return  0;

        cmd     = membarrier(MEMBARRIER_CMD_QUERY, 0);
        if (cmd < 0)
                return  -2;

        if (cmd & MEMBARRIER_CMD_PRIVATE_EXPEDITED) {
                mb_cmd  = MEMBARRIER_CMD_PRIVATE_EXPEDITED;
                if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0))
                        return  -3;
        } else if (cmd & MEMBARRIER_CMD_GLOBAL_EXPEDITED) {
                mb_cmd  = MEMBARRIER_CMD_GLOBAL_EXPEDITED;
                if (membarrier(MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, 0))
                        return  -4;
        } else {
                mb_cmd  = MEMBARRIER_CMD_GLOBAL;
        }

        done    = true;
        return  membarrier(mb_cmd, 0);
}

static
int     sigterm_init    (void)
{
        struct sigaction        sa = {0};

        if (mb_init())
                return  -1;

        sigterm = false;
        membarrier(mb_cmd, 0);

        sigemptyset(&sa.sa_mask);
        sa.sa_handler   = &sigterm_handler;
        if (sigaction(SIGTERM, &sa, NULL))
                return  -3;
        return  0;
}

static
void    sigterm_handler (int sig)
{

        (void)sig;

        sigterm = true;
        membarrier(mb_cmd, 0);
}
main.c

#include "libalx/base/socket/tcp/server.h"

#include <errno.h>
#include <stddef.h>
#include <stdlib.h>

#include <netdb.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>


static
int     get_addrs       (const char *server_port, struct addrinfo **addrs);
static
int     set_server      (int sd, int *optval, struct addrinfo *ad, int backlog);
static
int     set_socket      (struct addrinfo *addrs, int backlog);


int     tcp_server_open     (const char *server_port, int backlog)
{
        int             sd;
        struct addrinfo *addrs;

        sd      = -1;
        if (get_addrs(server_port, &addrs))
                return  -1;
        sd      = set_socket(addrs, backlog);
        freeaddrinfo(addrs);

        if (sd < 0)
                return  -2;
        return  sd;
}


static
int     get_addrs       (const char *server_port, struct addrinfo **addrs)
{
        struct protoent *tcp;
        struct addrinfo hint = {0};

        tcp     = getprotobyname("tcp");
        if (!tcp)
                return  -1;
        hint.ai_family          = AF_UNSPEC;
        hint.ai_socktype        = SOCK_STREAM;
        hint.ai_protocol        = tcp->p_proto;
        hint.ai_flags           = AI_PASSIVE;
        if (getaddrinfo(NULL, server_port, &hint, addrs))
                return  -1;
        return  0;
}

static
int     set_socket      (struct addrinfo *addrs, int backlog)
{
        int     val;
        int     sock;

        sock    = -1;
        for (struct addrinfo *ad = addrs; ad; ad = ad->ai_next) {
                sock = socket(ad->ai_family, ad->ai_socktype, ad->ai_protocol);
                if (sock < 0)
                        continue;
                if (!set_server(sock, &val, ad, backlog))
                        break;
                close(sock);
                sock    = -1;
        }

        return  sock;
}

static
int     set_server      (int sd, int *optval, struct addrinfo *ad, int backlog)
{

        *optval = 1;
        if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, optval, sizeof(*optval)))
                return  -1;
        if (bind(sd, ad->ai_addr, ad->ai_addrlen))
                return  -1;
        if (listen(sd, backlog))
                return  -1;
        return  0;
}
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

#include <sys/socket.h>
#include <unistd.h>

#include <linux/membarrier.h>

#define ALX_NO_PREFIX
#include <libalx/base/compiler/size.h>
#include <libalx/base/linux/membarrier.h>
#include <libalx/base/socket/tcp/server.h>


static  int             mb_cmd;
static  sig_atomic_t    sigterm;
static  int             tcp;


static
int     rob_init        (void);
static
int     rob_deinit      (void);
static
int     tcp_init        (void);
static
int     tcp_deinit      (void);

static
void    cam_session     (int cam);

static
int     mb_init         (void);
static
int     sigterm_init    (void);
static
void    sigterm_handler (int sig);


int     main            (void)
{
        int                     tcp;
        int                     cam;
        struct sockaddr_storage cam_addr = {0};
        socklen_t               cam_addr_len;
        int                     status;

        status  = 1;
        if (rob_init())
                goto out0;

        status++;
        cam_addr_len    = sizeof(cam_addr);
        do {
                cam = accept(tcp, (struct sockaddr *)&cam_addr, &cam_addr_len);
                if (cam < 0) {
                        goto retry;
                }

                cam_session(cam);
                close(cam);
        retry:
                asm volatile ("" : : : "memory");
        } while (!sigterm);

        status  = EXIT_SUCCESS;

        if (rob_deinit())
                status  += 32;
out0:
        fprintf(stderr, "rob: ERROR: main(): %i\n", status);

        return  status;
}


static
int     rob_init        (void)
{
        int     status;

        status  = -1;
        if (sigterm_init())
                goto err;
        status--;
        if (tcp_init())
                goto err;
        return  0;
err:
        fprintf(stderr, "rob: ERROR: rob_init(): %i\n", status);
        return  status;
}

static
int     rob_deinit      (void)
{
        int     status;

        status  = 0;
        if (tcp_deinit())
                status--;

        return  status;
}

static
int     tcp_init        (void)
{

        tcp     = -1;
        tcp     = tcp_server_open("23", 10);
        return  tcp < 0;
}

static
int     tcp_deinit      (void)
{
        return  close(tcp);
}

static
void    cam_session     (int cam)
{
        static  int i = 0;
        char    cam_data[BUFSIZ];
        ssize_t n;

        i++;
        while (true) {
                n = read(cam, cam_data, ARRAY_SIZE(cam_data) - 1);
                if (n < 0)
                        return;
                cam_data[n]     = 0;
                if (!n)
                        return;
                printf("%s\n", cam_data);
        }
}


static
int     mb_init         (void)
{
        static bool     done = false;
        int             cmd;

        if (done)
                return  0;

        cmd     = membarrier(MEMBARRIER_CMD_QUERY, 0);
        if (cmd < 0)
                return  -2;

        if (cmd & MEMBARRIER_CMD_PRIVATE_EXPEDITED) {
                mb_cmd  = MEMBARRIER_CMD_PRIVATE_EXPEDITED;
                if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0))
                        return  -3;
        } else if (cmd & MEMBARRIER_CMD_GLOBAL_EXPEDITED) {
                mb_cmd  = MEMBARRIER_CMD_GLOBAL_EXPEDITED;
                if (membarrier(MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED, 0))
                        return  -4;
        } else {
                mb_cmd  = MEMBARRIER_CMD_GLOBAL;
        }

        done    = true;
        return  membarrier(mb_cmd, 0);
}

static
int     sigterm_init    (void)
{
        struct sigaction        sa = {0};

        if (mb_init())
                return  -1;

        sigterm = false;
        membarrier(mb_cmd, 0);

        sigemptyset(&sa.sa_mask);
        sa.sa_handler   = &sigterm_handler;
        if (sigaction(SIGTERM, &sa, NULL))
                return  -3;
        return  0;
}

static
void    sigterm_handler (int sig)
{

        (void)sig;

        sigterm = true;
        membarrier(mb_cmd, 0);
}

您有一个名为
tcp
的文件范围变量和一个名为
tcp
的局部变量。这真是个坏主意。@user3386109哦,嘘**。我没看见。当我把它改成全球的时候,我应该把它删除。哈哈,是的。在这些事情上必须小心:)仔细观察输出,我认为编译器确实发现了问题。输出状态为“gcc返回1退出状态”。但无论如何都调用了链接器,您也得到了一个“ld returned 1 exit status”。@error path中的user3629249代码是正确的,不是吗?如果发生错误,我将返回一个负套接字,这意味着无法使用该套接字。该函数(也是me)的用户在使用套接字之前检查它是否为非负。您有一个名为
tcp
的文件范围变量和一个名为
tcp
的局部变量。这真是个坏主意。@user3386109哦,嘘**。我没看见。当我把它改成全球的时候,我应该把它删除。哈哈,是的。在这些事情上必须小心:)仔细观察输出,我认为编译器确实发现了问题。输出状态为“gcc返回1退出状态”。但无论如何都调用了链接器,您也得到了一个“ld returned 1 exit status”。@error path中的user3629249代码是正确的,不是吗?如果发生错误,我将返回一个负套接字,这意味着无法使用该套接字。该函数(也是me)的用户在使用套接字之前检查它是否为非负。