[En-Nut-Discussion] Ethernut stopping on an HTTP web request

Ole Reinhardt ole.reinhardt at embedded-it.de
Thu Feb 17 10:51:34 CET 2011


Hi Bill,

> I am using a AT91SAM7X256 development board as a proof of concept.  I am a
> long time user of Ethernut, but have encountered a problem never seen
> before.  I am using 4.8.8 stable release for the software.
> I have a communications port open and am collection data from a appliance at
> 38400 baud.  The message traffic is bursted out with about 95 bytes of data
> sent at a 1Sec rate.  I have a telnet session running as well and I can
> query the data with no issue.  When I attempt to display the data in a web
> page using active server pages, the board stops running completely.  Any
> suggestions as where to start debugging.  If I turn off the communications
> and then access throught the web, the pages display fine with the correct
> data.

Sounds like a stack overflow or a buffer overflow. A stack overflow
might happen if you calculated the needed stack for one of your threads
too low. There might not necessarily be a correlation to the http
threads as a stack overflow normaly overwrites data at a random address.
This will result either in corrup data (of only any variables are
overwritten) or in a crash (if any return address saved on the stack is
overwritten).


First solution would be to print out the stack in a regular way and
watch the running threads. Next give any thread some more stack.



For further debugging you can write an exception handler like described
here:

http://www.ethernut.de/en/documents/arm-exceptions.html

It will produce you a stack backtrace, so you can examine the last
functions that were called.

Some time ago I had a similar problem and wrote those two functions for
debugging purposes. You can call test_threads at several points in your
code and it will check the available stack for any running thread. If
it's going below the configured value a thread list will be dumped.

Hope this might help you...

Regards,

Ole Reinhardt


void show_threads(void)
{
    NUTTHREADINFO *tdp;
    NUTTIMERINFO *tnp;
    char *buffer;
    buffer = malloc(4096);
    
    strcpy(buffer, ("List of threads with
name,state,prio,stack,mem,timeout follows\r\n"));

    for (tdp = nutThreadList; tdp; tdp = tdp->td_next) {
        sprintf(&buffer[strlen(buffer)], "%s", tdp->td_name);
        switch (tdp->td_state) {
        case TDS_TERM:
            sprintf(&buffer[strlen(buffer)],"\tTerm\t");
            break;
        case TDS_RUNNING:
            sprintf(&buffer[strlen(buffer)],"\tRun\t");
            break;
        case TDS_READY:
            sprintf(&buffer[strlen(buffer)],"\tReady\t");
            break;
        case TDS_SLEEP:
            sprintf(&buffer[strlen(buffer)],"\tSleep\t");
            break;
        }
        sprintf(&buffer[strlen(buffer)],"%u\t%u", tdp->td_priority,
(u_int) tdp->td_sp - (u_int) tdp->td_memory);
        if (*((u_long *) tdp->td_memory) != DEADBEEF)
            sprintf(&buffer[strlen(buffer)],"\tCorrupted\t");
        else
            sprintf(&buffer[strlen(buffer)],"\tOK\t");

        if ((tnp = (NUTTIMERINFO *) tdp->td_timer) != 0)
            sprintf(&buffer[strlen(buffer)],"%lu\r\n",
tnp->tn_ticks_left);
        else
            sprintf(&buffer[strlen(buffer)],"None\r\n");
    }
    
    INFO("Threads: %s\r\n", buffer);
    free(buffer);
}

void test_threads(void)
{
    NUTTHREADINFO *tdp;
    u_int stack;
    
    for (tdp = nutThreadList; tdp; tdp = tdp->td_next) {
        stack = (u_int) tdp->td_sp - (u_int) tdp->td_memory;
        if ((tdp->td_name[0] == 'r') && (tdp->td_name[1] == 'x'))
continue;
        if ((tdp->td_name[0] == 'i') && (tdp->td_name[1] == 'd') &&
(tdp->td_name[2] == 'l')) continue;
        
        if (*((u_long *) tdp->td_memory) != DEADBEEF) {
            ERROR("!!! Corruptet: %s, %d\r\n", tdp->td_name, stack);
            show_threads();
        }
    
        if (stack < 700) {    
            ERROR("!!! StackLow: %s, %d\r\n", tdp->td_name, stack);
        }   
        if (stack < 300) {
            show_threads();
        }
    }
}





-- 

Thermotemp GmbH, Embedded-IT

Embedded Hard-/ Software and Open Source Development, 
Integration and Consulting

http://www.embedded-it.de

Geschäftsstelle Siegen - Steinstraße 67 - D-57072 Siegen - 
tel +49 (0)271 5513597, +49 (0)271-73681 - fax +49 (0)271 736 97

Hauptsitz - Hademarscher Weg 7 - 13503 Berlin
Tel +49 (0)30 4315205 - Fax +49 (0)30 43665002
Geschäftsführer: Jörg Friedrichs, Ole Reinhardt
Handelsregister Berlin Charlottenburg HRB 45978 UstID DE 156329280 




More information about the En-Nut-Discussion mailing list