Вопрос
Я проектирую протокол (в C) реализовать структуру сетевой структуры MOSE ASI, используя CNET (http://www.csse.uwa.edu.au/cnet/). Я получаю ошибку SIGSEGV во время выполнения, однако CNET компилирует сам файлы исходного кода (я не могу компилировать его через GCC), поэтому я не могу легко использовать любые инструменты отладки, такие как GDB, чтобы найти ошибку.
Вот используемые структуры, а код под вопросом:
typedef struct {
char *data;
} DATA;
typedef struct {
CnetAddr src_addr;
CnetAddr dest_addr;
PACKET_TYPE type;
DATA data;
} Packet;
typedef struct {
int length;
int checksum;
Packet datagram;
} Frame;
static void keyboard(CnetEvent ev, CnetTimerID timer, CnetData data)
{
char line[80];
int length;
length = sizeof(line);
CHECK(CNET_read_keyboard((void *)line, (unsigned int *)&length)); // Reads input from keyboard
if(length > 1)
{ /* not just a blank line */
printf("\tsending %d bytes - \"%s\"\n", length, line);
application_downto_transport(1, line, &length);
}
}
void application_downto_transport(int link, char *msg, int *length)
{
transport_downto_network(link, msg, length);
}
void transport_downto_network(int link, char *msg, int *length)
{
Packet *p;
DATA *d;
p = (Packet *)malloc(sizeof(Packet));
d = (DATA *)malloc(sizeof(DATA));
d->data = msg;
p->data = *d;
network_downto_datalink(link, (void *)p, length);
}
void network_downto_datalink(int link, Packet *p, int *length)
{
Frame *f;
// Encapsulate datagram and checksum into a Frame.
f = (Frame *)malloc(sizeof(Frame));
f->checksum = CNET_crc32((unsigned char *)(p->data).data, *length); // Generate 32-bit CRC for the data.
f->datagram = *p;
f->length = sizeof(f);
//Pass Frame to the CNET physical layer to send Frame to the require link.
CHECK(CNET_write_physical(link, (void *)f, (size_t *)f->length));
free(p->data);
free(p);
free(f);
}
Мне удалось найти, что линия: чек (CNET_WRITE_PHYSICAL (ссылка (void *) f, (size_t *) f-> длина)); вызывает SegFault, но я не могу выработать, почему. Любая помощь значительно ценится.
Решение
Я думаю, это третий параметр. Попробуй это:
CHECK(CNET_write_physical(link, (void *)f, (size_t *)(&f->length)));
В этой строке я предполагаю, что третий параметр ожидает указателя, потому что вы отличаете значение (size_t *)
. Отказ Но стоимость, которую вы отличаете, это простое целочисленное значение. Итак, всякий раз, когда функция разыгрывает адрес, содержащийся в этом значении, заключается в том, когда вы, вероятно, получите SIGSEGV.
С предложением, которое я предложил, вы бросаете указатель (&f->length)
. Отказ Таким образом, вы должны быть хороши, чтобы пойти, предположить, что функция эффективно ожидает указателя на переменной удерживающую размер.
Другие советы
Я вижу две проблемы здесь - sizeof(f)
дает вам размер указатель не Frame
, тогда вы назначаете size_t
-ти воспитательное значение f->length
, но позже бросил это size_t*
. Отказ Последнее, вероятно, является причиной ошибки сегментации.