У меня есть какой-то устаревший код, использующий указатель, предназначенный для «обхода» буфера массива символов. Указатель структуры используется для отправки данных по проводам, но вычисляет контрольную сумму и сохраняет ее в структуре перед отправкой. Однако происходит segfault, и, похоже, это происходит при использовании ftree-vectorize
. Похоже, это работало при компиляции в gcc 4.4.7
с такими же флагами. Это компилируется для 32-bit
.
Я получил код для запуска без ftree-vectorize
, и я не уверен, как векторизация работает на низком уровне. Я также добавил ftree-vectorizer-verbose=6
, чтобы попытаться прочитать журнал, но я действительно не мог понять из этого.
Я попытался удалить много #defines и получить код кратким и ясным ..
Следующие флаги также использовались для компиляции:
GCC_OPTIMIZATIONS ?= -march=i686 -mmmx -msse -msse2 -O1 -ftree-parallelize-loops=8 -fpredictive-commoning -ftree-vectorize -finline-functions
// a header for information about data
typedef struct Record_Hdr {
struct {
unsigned long message_id: 12;
unsigned long res: 2;
unsigned long fr_flag: 1;
unsigned long cr_flag: 1;
unsigned long message_length: 16;
} wrd0;
unsigned long sync_id;
struct {
unsigned long sequence_number: 8;
unsigned long app_flag2: 4;
unsigned long app_flag1: 4;
unsigned long destination_id: 8;
unsigned long source_id: 8;
} wrd2;
unsigned long timestamp;
unsigned long checksum;
} Record_Hdr;
// Header and data
typedef struct {
Record_Hdr hdr;
unsigned char data[1004];
} RECORD;
// method defined in another class used below
unsigned char sgf_pkt[1400];
int sgf_pkt_len = 0;
inline char* get_sgf_pkt_msg_ptr() {
return (char*)&sgf_pkt[sgf_pkt_len];
}
Код проблемы:
RECORD *out_msg = NULL;
int msg_length = 85;
out_msg = (RECORD*)mdt_io.get_pkt_msg_ptr();
// set the necessities
out_msg->hdr.wrd0.message_id = 0x25;
out_msg->hdr.wrd0.message_length = msg_length;
out_msg->hdr.wrd2.source_id = 104;
out_msg->hdr.wrd2.destination_id = 0;
out_msg->hdr.sync_id = 0x5555AAAA;
out_msg->hdr.timestamp = timeInTicks;
out_msg->hdr.checksum = 0;
// checksum calculation
unsigned long chkSum, *datap;
int i;
chkSum = 0;
datap = (unsigned long *) &(out_msg->hdr.wrd0);
// runs 85 times...
for (i=0; i < msg_length; i++) {
chkSum ^= *datap++; // SEG FAULTS HERE, usually at 84th index
}
out_msg->hdr.checksum = chkSum;
Попытался с помощью отладчика gdb проверить, не выходит ли массив sgf_pkt за пределы, но это не так. В целом, я пытаюсь понять, есть ли какие-либо проблемы с выравниванием памяти, о которых мне следует знать.
Спасибо