lwip-users
[Top][All Lists]
Advanced

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

RE: [lwip-users] Problem with NULL pcb->callback_arg


From: Bill Auerbach
Subject: RE: [lwip-users] Problem with NULL pcb->callback_arg
Date: Thu, 6 Aug 2009 08:12:10 -0400

What does your http_poll do?

 

From: address@hidden [mailto:address@hidden On Behalf Of Baptiste Chaboud-crousaz
Sent: Thursday, August 06, 2009 5:51 AM
To: address@hidden
Subject: Re: [lwip-users] Problem with NULL pcb->callback_arg

 

Hi all,

Since my problem is not resolved, I ask you again to help me.
I use the HTTP (RAW version) server provided by the lwip site in the /contrib/apps/httpserver_raw folder.

Sometimes, the argument passed to http_sent is NULL which leads an hardfault exception. In the majority of cases, there is no problem. This problem is avoided or limited when I increases the size of MEM_SIZE. But I have to drastically reduce this size to meet my hardware requirements.

My understanding is that a memory allocation is done out the memory space dedicted to lwip.
But I don' understand how it can be possible. All the results of memory allocation are checked. Would it be possible that there is a bug in lwip? If yes where?

What should I do?????

Best regards.
Baptiste

Quoting Baptiste Chaboud-crousaz <address@hidden>:

>
>
>   Hi,
>
>   For a better understanding I give a part of the code of my HTTP server:
>
>   ===============================================
>
>   void httpd_init(void)
> {
>   struct tcp_pcb *pcb;
>
>   pcb = tcp_new();
>   tcp_bind(pcb, IP_ADDR_ANY, 80);
>   pcb = tcp_listen(pcb);
>   tcp_accept(pcb, http_accept);
> }
>
>   ===============================================
>
>   static err_t
> http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
> {
>     struct http_connect_state* hcs;
>
>     tcp_setprio(pcb, TCP_PRIO_MIN);
>
>     /* Allocate memory for the structure that holds the state of the 
>  connection. */
>     hcs = mem_malloc(sizeof(struct http_connect_state));
>
>     if (hcs == NULL) {
>         return ERR_MEM;
>     }
>
>     /* Initialize the structure. */
>     hcs->file            = NULL;
>     hcs->resource_id    = 0;
>     hcs->method_id        = 0;
>     hcs->retries        = 0;
>
>     /* Tell TCP that this is the structure we wish to be passed for   
> our callbacks. */
>     tcp_arg(pcb, hcs);
>
>     /* Tell TCP that we wish to be informed of incoming data by a 
> call  to the http_recv() function. */
>     tcp_recv(pcb, http_recv);
>
>     tcp_err(pcb, conn_err);
>
>     tcp_poll(pcb, http_poll, 4);
>
>     return ERR_OK;
> }
>
>   ===============================================
>
>   static err_t
> http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
> {
>     struct http_connect_state* hcs;
>
>     hcs = arg;
>
>     if (ERR_OK == err)
>     {
>           if (NULL != p)
>         {
>             /* Inform TCP that we have taken the data. */
>             tcp_recved(pcb, p->tot_len);
>    
>             if (hcs->file == NULL)
>             {
>                 ProcessHttpRequest(hcs, p, &(pcb->remote_ip));
>                
>                 if (hcs->file != NULL)
>                 {
>                     pbuf_free(p);
>                     send_data(pcb, hcs);
>        
>                     /* Tell TCP that we wish be to informed of data   
> that has been
>                      successfully sent by a call to the http_sent()   
> function. */
>                     tcp_sent(pcb, http_sent);
>                 }
>                 else
>                 {
>                     pbuf_free(p);
>                     p = NULL;
>                 }             
>             }
>             else
>             {
>                 pbuf_free(p);
>                 p = NULL;
>             }
>         }
>    
>         if (NULL == p)
>         {
>             close_conn(pcb, hcs);
>         }
>     }
>
>     return err;
> }
>
>   ===============================================
>
>   static err_t
> http_sent(void *arg, struct tcp_pcb *pcb, u16_t len)
> {
>   struct http_connect_state* hcs;
>
>   if(arg != NULL)
>   {
>       hcs = arg;
>       hcs->retries = 0;
>       send_data(pcb, hcs);
>   }
>
>   return ERR_OK;
> }
>
>   ===============================================
>
>   static void
> close_conn(struct tcp_pcb *pcb, struct http_connect_state* hcs)
> {
>     tcp_arg(pcb, NULL);
>     tcp_sent(pcb, NULL);
>     tcp_recv(pcb, NULL);
>
>     if(hcs->file) {
>         wfs_close(hcs->file);
>         hcs->file = NULL;
>     }
>
>     mem_free(hcs);
>     tcp_close(pcb);
> }
>
>   ===============================================
>
>   As you can see at the HTTP init, the http_accept is set as callback
> for ACCEPT and in http_recv, http_sent is set as callback which will
> be called by TCP_EVENT_SENT.
>
>   When I use a single web browser there is no problem: the arg value
> passed to http_sent is never NULL. But when I launch another web
> browser, this parameter becomes sometimes NULL. It seems to be when
> the stack receives the new SYN frame from the client.
>
>   You said "That could be a hint that you are writing beyond allocated memory
> somwhere and overwrite the memory where the PCB lies with zeros". But
> I always check the returned value when I make a memory allocation. If
> the functions used for memory allocation return an invalid space =>
> there is a bug in the stack!
>
>   Baptiste
>
>   Quoting "address@hidden" <address@hidden>:
>> Baptiste Chaboud-crousaz wrote:
>>>
>>> Sometimes, the face trouble with my callback http_connect - 
>>> called   by the macro TCP_EVENT_SENT - because "arg" is null.
>>>
>>
>> I don't understand that one:
>> a) there is no function 'http_connect' in the code you posted
>> b) TCP_EVENT_SENT calls the function set by calling tcp_sent(pcb, fn) -
>> the code you posted doesn't call tcp_sent().
>> c) I would have thought a connect function would be used with a client,
>> not a server - whereas an accept function (as you posted) is used with
>> a server, not a client)
>>
>>> My understanding is that the http_accept function binds a pcb to   
>>> an  argument by a call to tcp_arg(...). I don't undersatnd why    
>>> sometimes my callback is called with a NULL arg!!!
>>>
>>> This issue seems to be avoided/limited by increasing the size of    
>>> MEM_SIZE and PBUF_POOL_SIZE.
>>>
>>
>> That could be a hint that you are writing beyond allocated memory
>> somwhere and overwrite the memory where the PCB lies with zeros...
>>
>>> If anybody has an idea, let me knwo about it...
>>>
>>
>> Except for the above, I'm afraid I don't have an idea. Unless you call
>> *tcp_arg(pcb, NULL) somewhere else, of course...*
>>
>> Does the argument get NULL during the connection or right at the start?
>>
>>
>> Simon
>>
>>
>> _______________________________________________
>> lwip-users mailing list
>> address@hidden
>> http://lists.nongnu.org/mailman/listinfo/lwip-users


reply via email to

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