开启telnet后, 在msh中使用netstat指令, 程序进入死循环直至崩溃.
问题定位: 使用netstat指令会调用ethernetif.c中list_tcps()函数, 调用该函数时使用了rt_enter_critical(); 随后程序调用了rt_kprintf(); 因为切换了telnet作为console, rt_kprintf()会引起telnet_write()调用, 该函数代码中使用了rt_mutex_take(telnet->tx_ringbuffer_lock, RT_WAITING_FOREVER); rt_mutex_take()函数会检查scheduler是否被锁, 实际上因为之前调用rt_enter_critical()已经将scheduler上锁, 会打印调试信息调用rt_kprintf. 至此死循环形成rt_kprintf -> telnet_write -> rt_mutex_take -> rt_kprintf->...死循环形成.
解决方法: 同时需要修改: void list_udps(void); 如果使用list_fd命令也会出现类似问题, 需要修改dfs.c中的这个函数:int list_fd(void). 附: 修改的代码. void list_tcps(void) { rt_uint32_t num = 0; char local_ip_str[16]; char remote_ip_str[16]; extern struct tcp_pcb *tcp_active_pcbs; extern union tcp_listen_pcbs_t tcp_listen_pcbs; extern struct tcp_pcb *tcp_tw_pcbs; char *buff = rt_malloc(1024); char *buff_start = buff; rt_enter_critical(); buff += rt_sprintf(buff, "Active PCB states:
"); for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip))); strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip))); buff += rt_sprintf(buff, "#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ", num++, local_ip_str, pcb->local_port, remote_ip_str, pcb->remote_port, pcb->snd_nxt, pcb->rcv_nxt); buff += rt_sprintf(buff, "state: %s
", tcp_debug_state_str(pcb->state)); } rt_exit_critical(); rt_kprintf(buff_start); rt_enter_critical(); buff = buff_start; buff += rt_sprintf(buff, "Listen PCB states:
"); num = 0; for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { buff += rt_sprintf(buff,"#%d local port %d ", num++, pcb->local_port); buff += rt_sprintf(buff,"state: %s
", tcp_debug_state_str(pcb->state)); } rt_exit_critical(); rt_kprintf(buff_start); rt_enter_critical(); buff = buff_start; buff += rt_sprintf(buff,"TIME-WAIT PCB states:
"); num = 0; for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { strcpy(local_ip_str, ipaddr_ntoa(&(pcb->local_ip))); strcpy(remote_ip_str, ipaddr_ntoa(&(pcb->remote_ip))); buff += rt_sprintf(buff, "#%d %s:%d <==> %s:%d snd_nxt 0x%08X rcv_nxt 0x%08X ", num++, local_ip_str, pcb->local_port, remote_ip_str, pcb->remote_port, pcb->snd_nxt, pcb->rcv_nxt); buff += rt_sprintf(buff,"state: %s
", tcp_debug_state_str(pcb->state)); } rt_exit_critical(); rt_kprintf(buff_start); rt_free(buff_start);
}
|