lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] Assertion failed in TCP code


From: David Hammerton
Subject: [lwip-users] Assertion failed in TCP code
Date: Thu, 24 Dec 2009 14:42:37 +1100

Hi there,

I'm getting a strange assertion failure in lwIP. The assertion failure is this:

        if (pcb->snd_queuelen != 0) {

          LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL ||

                      pcb->unsent != NULL);

        }



On tcp_in.c : 861.

I'm trying to figure out what could possibly be causing this, and I've seen a few other emails on the list about it (ie this one:
http://www.mail-archive.com/address@hidden/msg00519.html
and:
http://www.mail-archive.com/address@hidden/msg00645.html
)
and I can see that threading could be an issue, but I can't see that I'm doing anything wrong.

I am running in a multi-threaded environment: I'm running on a AVR32 with FreeRTOS. There is one thread (A) that is reading the ethernet packets from the MAC (Basically calling low_level_input and ethernet_input.), another is running a UDP service, based on the sockets API (B), and yet another is running a TCP service, also based on the sockets API (C). Finally, I think (?) that lwip is creating its own thread (D) with tcpip_init.

Thread (B) doesn't seem to be causing any issues, and since the assertion is in the TCP stack, I'm guessing we can ignore it (in fact, if I disable thread B, I still get the problem). The issue seems to be with thread (C). All it is doing (For now), is essentially:
lwip_socket(...), lwip_bind(...), lwip_listen(...)
while (1)
{
    lwip_accept(...)
    lwip_recv(...)
    lwip_send(...)
    lwip_close(...)
}

After a number of connections to the socket in thread (C), thread (A) will dies with the assertion failure. The backtrace looks something like this:

#0  0x8000b0e2 in tcp_receive (pcb=0x2dd0) at ./lwIP-1.3.0/core/tcp_in.c:861
#1  0x8000a8e6 in tcp_process (pcb=0x2dd0) at ./lwIP-1.3.0/core/tcp_in.c:645
#2  0x80009d46 in tcp_input (p=0x39cc, inp=0x5a4c) at ./lwIP-1.3.0/core/tcp_in.c:295
#3  0x80012df6 in ip_input (p=0x39cc, inp=0x5a4c) at ./lwIP-1.3.0/core/ipv4/ip.c:412
#4  0x80019554 in ethernet_input (p=0x39cc, netif=0x5a4c) at ./lwIP-1.3.0/netif/etharp.c:1150

And here is some of the data:

(gdb) p pcb->unsent
$2 = (struct tcp_seg *) 0x0
(gdb) p pcb->unacked
$3 = (struct tcp_seg *) 0x2f28
(gdb) p pcb->snd_queuelen
$4 = 1

The documentation seems to be *very* slim on how exactly all this is supposed to work. Since I'm using the sockets APIs, I take it I don't need to worry about locking when accessing the lwIP stack (?), as that's what's mentioned in the small amounts of documentation/emails I've read. But does that take care of locking issues between the MAC thread (A) and the socket thread (C), or should I be doing my own locking there? Or is there some alternative to the MAC thread, that is more appropriate for use with the sockets API? Or is the tcpip thread (D) interfering somehow? If the tcpip_thread is supposed to deal with all tcp data, how come the MAC thread is processing the data (As seen in the backtrace).

Any help would be appreciated!

Thanks

David

--
David Hammerton


reply via email to

[Prev in Thread] Current Thread [Next in Thread]