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 i
th 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.