在停止等待协议实现中使用 pthread 时的 SIGSEGV

Posted

技术标签:

【中文标题】在停止等待协议实现中使用 pthread 时的 SIGSEGV【英文标题】:SIGSEGV when using pthreads in Stop-and-Wait Protocol implementation 【发布时间】:2013-02-26 03:17:53 【问题描述】:

我是一名大学生,作为网络作业的一部分,我需要执行停止等待协议。问题陈述需要使用 2 个线程。我是线程新手,但是在浏览了 pthreads API 的手册页之后,我编写了基本代码。但是,在成功创建线程后(在执行作为参数传递给 pthread_create() 的函数的第一行时)出现分段错误。

typedef struct packet_generator_args

    int max_pkts;
    int pkt_len;
    int pkt_gen_rate;
 pktgen_args;

/* generates and buffers packets at a mean rate given by the
pkt_gen_rate field of its argument; runs in a separate thread  */
void *generate_packets(void *arg)

    pktgen_args *opts = (pktgen_args *)arg; // error occurs here
    buffer = (char **)calloc((size_t)opts->max_pkts, sizeof(char *));
    if (buffer == NULL)
        handle_error("Calloc Error");
    //front = back = buffer;
    ........

    return 0;

主线程从此缓冲区读取数据包并运行停止等待算法。

pktgen_args thread_args;
thread_args.pkt_len = DEF_PKT_LEN;
thread_args.pkt_gen_rate = DEF_PKT_GEN_RATE;
thread_args.max_pkts = DEF_MAX_PKTS;

/* initialize sockets and other data structures */
.....
pthread_t packet_generator;
pktgen_args *thread_args1 = (pktgen_args *)malloc(sizeof(pktgen_args));
memcpy((void *)thread_args1, (void *)&thread_args, sizeof(pktgen_args));
retval = pthread_create(&packet_generator, NULL, &generate_packets, (void *)thread_args1);
if (retval != 0)
    handle_error_th(retval, "Thread Creation Error");
.....
/* send a fixed no of packets to the receiver wating for ack for each. If
the ack is not received till timeout occurs resend the pkt */
.....

我曾尝试使用 gdb 进行调试,但无法理解为什么我的 generate_packets() 函数的第一行会出现分段错误。希望你们中的一个可以提供帮助。如果有人需要额外的上下文,可以在http://pastebin.com/Z3QtEJpQ 获得整个代码。我在这里花了好几个小时才真正陷入困境。任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

您将buffer 初始化为NULL

 char **buffer = NULL;

然后在main() 无需进一步操作,您尝试解决它:

while (!buffer[pkts_ackd]); /* wait as long as the next pkt has not

基本上,我半知半解的猜测是您的线程尚未生成任何数据包,并且您在尝试访问 NULL 中的元素时崩溃。

[162][04:34:17] vlazarenko@alluminium (~/tests) > cc -ggdb -o pthr pthr.c 2> /dev/null
[163][04:34:29] vlazarenko@alluminium (~/tests) > gdb pthr
GNU gdb 6.3.50-20050815 (Apple version gdb-1824) (Thu Nov 15 10:42:43 UTC 2012)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done

(gdb) run
Starting program: /Users/vlazarenko/tests/pthr 
Reading symbols for shared libraries +............................. done

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000000
0x000000010000150d in main (argc=1, argv=0x7fff5fbffb10) at pthr.c:205
205         while (!buffer[pkts_ackd]); /* wait as long as the next pkt has not
(gdb) 

【讨论】:

主要的教训是,原贴应该学会使用gdb和使用gcc -Wall -g编译

以上是关于在停止等待协议实现中使用 pthread 时的 SIGSEGV的主要内容,如果未能解决你的问题,请参考以下文章

信道速率为8kb/s,采用停止等待协议,传播时延tp=20ms,假定信道无差错,确认帧长度和处理时间不记

使用 pthreads 时的后台线程(很好,优先级)

停止等待协议问题

计算机网络-可靠传输-停止等待协议

java利用socket通信模拟实现ARQ停止等待协议

一个信道的数据传输速率为4kb/s,单向传播时延为30ms,如果使停止-等待协议的信道最大利用率达到80%,那么要求的数据帧长度至少为( )