[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [lwip-users] Problem with NULL pcb->callback_arg
From: |
Baptiste Chaboud-crousaz |
Subject: |
RE: [lwip-users] Problem with NULL pcb->callback_arg |
Date: |
Thu, 6 Aug 2009 15:00:45 +0200 |
User-agent: |
Internet Messaging Program (IMP) H3 (4.1.6) |
Hi,
please find here my function http_poll:
static err_t
http_poll(void *arg, struct tcp_pcb *pcb)
{
struct
http_connect_state* hcs;
hcs = arg;
if (hcs == NULL)
{
tcp_abort(pcb);
return ERR_ABRT;
} else
{
++hcs->retries;
if (hcs->retries >= 4)
{
tcp_abort(pcb);
return ERR_ABRT;
}
send_data(pcb, hcs);
}
return
ERR_OK;
}
Can you explain me what is the purpose of this
function?
Baptiste
Quoting Bill Auerbach <address@hidden>:
> 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
>
>
- [lwip-users] Problem with NULL pcb->callback_arg, Baptiste Chaboud-crousaz, 2009/08/04
- Re: [lwip-users] Problem with NULL pcb->callback_arg, address@hidden, 2009/08/04
- Re: [lwip-users] Problem with NULL pcb->callback_arg, Baptiste Chaboud-crousaz, 2009/08/04
- Re: [lwip-users] Problem with NULL pcb->callback_arg, Baptiste Chaboud-crousaz, 2009/08/06
- RE: [lwip-users] Problem with NULL pcb->callback_arg, Bill Auerbach, 2009/08/06
- RE: [lwip-users] Problem with NULL pcb->callback_arg,
Baptiste Chaboud-crousaz <=
- Re: [lwip-users] Problem with NULL pcb->callback_arg, Simon Goldschmidt, 2009/08/06
- Re: [lwip-users] Problem with NULL pcb->callback_arg, Baptiste Chaboud-crousaz, 2009/08/06
- Re: [lwip-users] Problem with NULL pcb->callback_arg, Chris_S, 2009/08/06
- [lwip-users] [TCP Previous segment lost] / [TCP Out-Of-Order] (HTTPd-RAW), Chris_S, 2009/08/10
- Re: [lwip-users] [TCP Previous segment lost] / [TCP Out-Of-Order] (HTTPd-RAW), Kieran Mansley, 2009/08/10
- Re: [lwip-users] [TCP Previous segment lost] / [TCP Out-Of-Order] (HTTPd-RAW), Chris_S, 2009/08/10