This is a really nasty breakage since the symptom consists of stack 
corruption.  In my case, I was able to observe the problem by adding 
some printf's in src/flash/nand.c with the execution path below.

src/flash/nand.c, line 1200, in handle_nand_erase_command():

        p = get_nand_device_by_num(strtoul(args[0], NULL, 0));
        if (p)
        {
                int first = strtoul(args[1], NULL, 0);
                int last = strtoul(args[2], NULL, 0);

                if ((retval = nand_erase(p, first, last)) == ERROR_OK)
[...]

Here the variable p is assigned the same value as the global variable 
nand_devices because there is only one device.  Then p is passed to 
nand_erase().  So far so good.

src/flash/nand.c, line 697, in nand_erase():

            retval = device->controller->nand_ready ?
                            device->controller->nand_ready(device, 1000) :
                            nand_poll_ready(device, 1000);

Here the variable p is called "device" instead.  Just before the code 
above, the global variable nand_devices and local variable device have 
the same value as before.  So far so good.  nand_poll_ready() is called 
with the value of the local variable "device".

src/flash/nand.c, line 410, in nand_poll_ready():

More instrumentation within nand_poll_ready() still shows that global 
nand_devices and local device are the same.  A call to 
device->controller->read_data() is performed, which in my case is 
orion_nand_read() wrapping a call to target_read_u8().  So far so good.

src/flash/nand.c, line 700, back in nand_erase():

As soon as nand_poll_ready() returns, then the _local_ variable "device" 
is corrupted!!!  The global variable nand_devices is still unchanged, 
but local variable device is crap, pointing to a bad address.  On line 
705 the call to nand_read_status() is passing that bad device pointer, 
and a segmentation fault occurs within that function.

Now this is extremely worrisome that a local variable on the stack gets 
corrupted by some buggy code down the call chain of target_read_u8().  
Backing to rev 1729 apparently "fixes" the issue, but I can't tell if at 
that point the corruption simply moved elsewhere unnoticed.

Also, rev 1729 is dog slow for NAND flashing.  It takes more than 5 
minutes to flash 400KB, while before the recent shurn it took only 80 
secs.  USB performance is supposed to be back in latest svn trunk but I 
can't test it.

The host machine is a x86-64 running Fedora 10 while the target is a 
Feroceon/SheevaPlug.


Nicolas
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to