Segfault on the code below, where is the error?

Advertisements

The code:

#include <list>
#include <thread>
#include <sys/poll.h>

struct xsk_ring_stats {
    unsigned long rx_frags;
    unsigned long rx_npkts;
    unsigned long tx_frags;
    unsigned long tx_npkts;
    unsigned long rx_dropped_npkts;
    unsigned long rx_invalid_npkts;
    unsigned long tx_invalid_npkts;
    unsigned long rx_full_npkts;
    unsigned long rx_fill_empty_npkts;
    unsigned long tx_empty_npkts;
    unsigned long prev_rx_frags;
    unsigned long prev_rx_npkts;
    unsigned long prev_tx_frags;
    unsigned long prev_tx_npkts;
    unsigned long prev_rx_dropped_npkts;
    unsigned long prev_rx_invalid_npkts;
    unsigned long prev_tx_invalid_npkts;
    unsigned long prev_rx_full_npkts;
    unsigned long prev_rx_fill_empty_npkts;
    unsigned long prev_tx_empty_npkts;
};

struct xsk_app_stats {
    unsigned long rx_empty_polls {};
    unsigned long fill_fail_polls {};
    unsigned long copy_tx_sendtos {};
    unsigned long tx_wakeup_sendtos {};
    unsigned long opt_polls {};
    unsigned long prev_rx_empty_polls {};
    unsigned long prev_fill_fail_polls {};
    unsigned long prev_copy_tx_sendtos {};
    unsigned long prev_tx_wakeup_sendtos {};
    unsigned long prev_opt_polls {};
};

struct xsk_driver_stats {
    unsigned long intrs;
    unsigned long prev_intrs;
};

struct xsk_umem_info {
    struct xsk_ring_prod fq;
    struct xsk_ring_cons cq;
    struct xsk_umem *umem;
    void *buffer;
};

struct xsk_socket_info {
    xsk_ring_cons rx {};
    xsk_ring_prod tx {};
    xsk_umem_info *umem {};
    xsk_socket *xsk {};
    xsk_ring_stats ring_stats {};
    xsk_app_stats app_stats {};
    xsk_driver_stats drv_stats {};
    uint32_t outstanding_tx {};
};

#define NUM_SOCKS 12

static int num_socks = 0;

static xsk_socket_info** xsks = new xsk_socket_info*[NUM_SOCKS];

static void l2fwd_all(int i)
{
    pollfd fds[1] = {};

    auto xsk = xsks[i];

    fds[i].fd = xsk_socket__fd(xsk->xsk);
    fds[i].events = POLLIN;
    xsk->app_stats.opt_polls++; //HERE IS THE PROBLEM!
}

int main(){
    for (int i = 0; i < NUM_SOCKS; i++)
        xsks[num_socks++] = new xsk_socket_info {};

    std::list<std::thread> threads {};

    for(int i = 0; i < num_socks; i++)
        l2fwd_all(i);
}

The Problem:

SIGSEGV (Segmentation fault) at line xsk->app_stats.opt_polls++;

I’m racking my brains trying to find a solution to this problem, I believe it’s related to the way I’m allocating the memory.

Honestly, I couldn’t find the problem, I’ve been in this dilemma for 6 hours

Solve the code problem

I believe that there is no room in this post for improvements in terms of explaining the error, because it is very small

But if I failed, please leave a comment before the negative one.

Online Demo:
https://replit.com/@LucasPaixaoPaix/FirsthandWorthyGlobalarrays#main.cpp

Strangely, no error was returned in the replit, only on my 64 bit Linux server

—– AFTER DEBUG WITH -fsanitize=address -g -W -Wall —–

/tmp/tmp.zc9dBNHYKe/cmake-build-debug/CesKit -i eth0 -l -N -p -b 256 -M -Q
Signal: SIGSEGV (Segmentation fault)
AddressSanitizer:DEADLYSIGNAL
=================================================================
==66457==ERROR: AddressSanitizer: SEGV on unknown address 0x000100000130 (pc 0x00000040c548 bp 0xfffffffff350 sp 0xfffffffff330 T0)
==66457==The signal is caused by a READ memory access.
    #0 0x40c548 in l2fwd_all ../test.cpp:95
    #1 0x40c610 in main ../test.cpp:105
    #2 0x400001060798 in __libc_start_call_main (/lib64/libc.so.6+0x2c798)
    #3 0x400001060868 in __libc_start_main_alias_2 (/lib64/libc.so.6+0x2c868)
    #4 0x402dac in _start (/tmp/tmp.zc9dBNHYKe/cmake-build-debug/CesKit+0x402dac)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ../test.cpp:95 in l2fwd_all
==66457==ABORTING

Process finished with exit code 1

>Solution :

There is no problem with xsks pointer allocation and access. The problem lies here:

pollfd fds[1] = {};

fds is an array of size 1 and here your program trying to access ith element of fds:

fds[i].fd = xsk_socket__fd(xsk->xsk);
fds[i].events = POLLIN;

any value of i which is greater than 0, it will try to access the array beyond it’s size, which is UB and can result in segmentation fault.

Leave a ReplyCancel reply