What does your http_poll do?
From: [email protected] [mailto:[email protected]] On Behalf Of Baptiste Chaboud-crousaz Sent: Thursday, August 06, 2009 5:51 AM To: [email protected] 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 <[email protected]>: > > > 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 "[email protected]" <[email protected]>: >> 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 >> [email protected] >> http://lists.nongnu.org/mailman/listinfo/lwip-users
_______________________________________________ lwip-users mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/lwip-users
