As the title says... Chat on...

User avatar
By wjr
#61117 Im building on a debian jessie.
Feel at home, here :-)
Still struggling with git :|

What I did:
- forked the official git to my own account
- switched to dev in the web interface
- cloned this (expecting dev)
- built with make
- flashed,
- found the mismatch - realized that I had a master build
- switched to dev ( so i thoght) but still had a mismatch
- tried a make clean, deleted the sdk directory, checked user_version.h but still got a mismatch
- did a new clone, checkout dev first and then build, and now it works

There is a version string in the top Makefile - maybe this is more important than user_version.h
Code: Select all# SDK version NodeMCU is locked to
SDK_VER:=2.0.0

Now the correct SDK is imported:
Code: Select all~/test/esp-SDK/nodemcu-firmware$ ls sdk
esp_iot_sdk_v2.0.0

The module's greeting looks consistent now
Code: Select allNodeMCU 2.0.0-wolfgangr build 20170116 powered by Lua 5.1.4 on SDK 2.0.0(656edbf)

and also
Code: Select all> =node.info()
2   0   0   1042729   1458415   4096   0   40000000


looks like "make clean" does not clean the sdk import.
Might help to read some sources&docs, but there are so many of them :o
User avatar
By wjr
#61212 HEAD BANGS the METAL :evil:

How can I debug boot loops?

To get things on the move, I tried this tutorial:
http://blog.mclemon.io/esp8266-contribu ... -ecosystem
with source code living here:
https://github.com/smcl/nodemcu-firmwar ... les/test.c

Fine, I hoped: It even has a ping example which interfaces to lwIP . great, we might borrow from it to implement a Lua wrapper to lwIP netif :-)
Obviusly I screwed somthing . fine, so I can learn to debug.

I can make and flash, can call my test_ping() without argument and get the programmed message "no address specified" . So my test function gets properly called at least.

But when I try with arguments, I get module reboot with two different reproducible behaviour:

String not parseable as IP -> immediate reboot
Code: Select all=test.ping("foo")
> Fatal exception 28(LoadProhibitedCause):
epc1=0x40260651, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 27292, room 16
tail 12
chksum 0xe9
ho 0 tail 12 room 4
load 0x3ffe8000, len 2212, room 12
tail 8
chksum 0x04
load 0x3ffe88a4, len 136, room 0
tail 8
chksum 0x10
csum 0x10


proper IP adress -> reboot after short delay
Code: Select all=test.ping("192.168.1.12")
> Fatal exception 28(LoadProhibitedCause):
epc1=0x4026043b, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000008, depc=0x00000000

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x40100000, len 27292, room 16
tail 12
chksum 0xe9
ho 0 tail 12 room 4
load 0x3ffe8000, len 2212, room 12
tail 8
chksum 0x04
load 0x3ffe88a4, len 136, room 0
tail 8
chksum 0x10
csum 0x10


I googled the message and found
viewtopic.php?p=18630&sid=a4cefec04afe9ddc9bd85f30657a2eee#p18630
28 means "LoadProhibitedCause"
"A load referenced a page mapped with an
attribute that does not permit loads [Region
Protection Option or MMU Option]"

Epc1 is the program counter where the exception occured and excvaddr is the address accessed.
Using the mapfile from the linker you typically can pinpoint the function of the problem and using objdump
you can locate the exact code position in c Code.


Well - fine.
First question: where does this wisdom come from?
There must be more of it, I'd like to dive in....

I could find some
Code: Select all.../nodemcu-firmware/app/mapfile


and searched for adresses close to the Epc1 - bingo - they point right into my test modules:
Code: Select all*fill*         0x000000004026041b        0x1 ffffffff
 .text.ping_received
                0x000000004026041c       0xb0 modules/.output/eagle/debug/lib/libmodules.a(test.o)
                                         0xfc (size before relaxing)
                0x0000000040260428                ping_received
 .text.test_ping
                0x00000000402604cc       0xf5 modules/.output/eagle/debug/lib/libmodules.a(test.o)
                                        0x165 (size before relaxing)
 *fill*         0x00000000402605c1        0x3 ffffffff
 .text.test_add
                0x00000000402605c4       0x45 modules/.output/eagle/debug/lib/libmodules.a(test.o)
                                         0x5d (size before relaxing)
 *fill*         0x0000000040260609        0x3 ffffffff
 .text.ping_by_hostname$part$0
                0x000000004026060c       0x2a modules/.output/eagle/debug/lib/libmodules.a(test.o)
                                         0x36 (size before relaxing)
 *fill*         0x0000000040260636        0x2 ffffffff
 .text.ping_by_hostname
                0x0000000040260638       0x45 modules/.output/eagle/debug/lib/libmodules.a(test.o)
                                         0x5d (size before relaxing)
 *fill*         0x000000004026067d        0x3 ffffffff
 .text.unregister_lua_cb


So I tried to apply some "educted guess" to "objdump" and did
Code: Select allxtensa-lx106-elf-objdump -S test.o | less


which yields
Code: Select allDisassembly of section .text.ping_received:

00000000 <ping_received-0x38>:
        ...
   8:   ffd8f0          excw
   b:   ff              .byte 0xff
        ...

00000038 <ping_received>:
  38:   f0c112          addi    a1, a1, -16
  3b:   30a492          movi    a9, 0x430
  3e:   0228            l32i.n  a2, a2, 0
  40:   21c9            s32i.n  a12, a1, 8
  42:   01e9            s32i.n  a14, a1, 0
  44:   3109            s32i.n  a0, a1, 12
  46:   11d9            s32i.n  a13, a1, 4
  48:   c01190          sub     a1, a1, a9
  4b:   1228            l32i.n  a2, a2, 4
  4d:   03cd            mov.n   a12, a3
  4f:   10c132          addi    a3, a1, 16
  52:   04d3e2          addmi   a14, a3, 0x400
  55:   4e29            s32i.n  a2, a14, 16
  57:   10a422          movi    a2, 0x410
  5a:   232a            add.n   a2, a3, a2
  5c:   10a042          movi    a4, 16
  5f:   203ee0          or      a3, a14, a14
  62:   ffeb01          l32r    a0, 10 <ping_received-0x28>
  65:   0000c0          callx0  a0
  68:   ffe621          l32r    a2, 0 <ping_received-0x38>
  6b:   0248            l32i.n  a4, a2, 0
  6d:   feaf22          movi    a2, -2
  70:   541427          beq     a4, a2, c8 <ping_received+0x90>
  73:   ffe4d1          l32r    a13, 4 <ping_received-0x34>
  76:   ffe431          l32r    a3, 8 <ping_received-0x30>
  79:   002d22          l32i    a2, a13, 0
  7c:   ffe601          l32r    a0, 14 <ping_received-0x24>
  7f:   0000c0          callx0  a0
  82:   0d28            l32i.n  a2, a13, 0
  84:   4c38            l32i.n  a3, a12, 16
  86:   ffe401          l32r    a0, 18 <ping_received-0x20>
  89:   0000c0          callx0  a0
  8c:   0d28            l32i.n  a2, a13, 0
  8e:   0e3d            mov.n   a3, a14
  90:   ffe301          l32r    a0, 1c <ping_received-0x1c>
  93:   0000c0          callx0  a0
  96:   0d28            l32i.n  a2, a13, 0
  98:   022c32          l32i    a3, a12, 8
  9b:   ffe101          l32r    a0, 20 <ping_received-0x18>
  9e:   0000c0          callx0  a0
  a1:   0d28            l32i.n  a2, a13, 0
  a3:   1c0c32          l8ui    a3, a12, 28
  a6:   ffdf01          l32r    a0, 24 <ping_received-0x14>
  a9:   0000c0          callx0  a0
  ac:   0d28            l32i.n  a2, a13, 0
  ae:   1c38            l32i.n  a3, a12, 4
  b0:   ffde01          l32r    a0, 28 <ping_received-0x10>
  b3:   0000c0          callx0  a0
  b6:   0d28            l32i.n  a2, a13, 0
  b8:   05a032          movi    a3, 5
  bb:   00a042          movi    a4, 0
  be:   ffdb01          l32r    a0, 2c <ping_received-0xc>
  c1:   0000c0          callx0  a0
  c4:   000886          j       ea <ping_received+0xb2>
  c7:   1c2800          excw



// https://github.com/smcl/nodemcu-firmware/blob/cc04aaf92c1c076c30ef0b0eee43b3f924137440/app/modules/test.c

void ping_received(void *arg, void *data) {
  ca:   1c0c72          l8ui    a7, a12, 28
  cd:   0129            s32i.n  a2, a1, 0
    struct ping_resp *pingresp = (struct ping_resp*)data;

    char ipaddrstr[16];
    ip_addr_t source_ip;
   
    source_ip.addr = pingopt->ip;
  cf:   ffcf31          l32r    a3, c <ping_received-0x2c>


// https://github.com/smcl/nodemcu-firmware/blob/cc04aaf92c1c076c30ef0b0eee43b3f924137440/app/modules/test.c

void ping_received(void *arg, void *data) {
  d2:   4c48            l32i.n  a4, a12, 16
  d4:   2c68            l32i.n  a6, a12, 8
  d6:   10c122          addi    a2, a1, 16
  d9:   0e5d            mov.n   a5, a14
    struct ping_resp *pingresp = (struct ping_resp*)data;

    char ipaddrstr[16];
    ip_addr_t source_ip;
   
    source_ip.addr = pingopt->ip;
  db:   ffd501          l32r    a0, 30 <ping_received-0x8>



// https://github.com/smcl/nodemcu-firmware/blob/cc04aaf92c1c076c30ef0b0eee43b3f924137440/app/modules/test.c

void ping_received(void *arg, void *data) {
  de:   0000c0          callx0  a0
    struct ping_resp *pingresp = (struct ping_resp*)data;

    char ipaddrstr[16];
    ip_addr_t source_ip;
   
    source_ip.addr = pingopt->ip;
  e1:   10c122          addi    a2, a1, 16
  e4:   ffd401          l32r    a0, 34 <ping_received-0x4>
    ipaddr_ntoa_r(&source_ip, ipaddrstr, sizeof(ipaddrstr));
  e7:   0000c0          callx0  a0
  ea:   30a492          movi    a9, 0x430
  ed:   119a            add.n   a1, a1, a9
  ef:   3108            l32i.n  a0, a1, 12
  f1:   21c8            l32i.n  a12, a1, 8
  f3:   11d8            l32i.n  a13, a1, 4
  f5:   01e8            l32i.n  a14, a1, 0
  f7:   10c112          addi    a1, a1, 16

    // if we've registered a lua callback function, retrieve
    // it from registry + call it, otherwise just print the ping
    // response in a similar way to the standard iputils ping util
    if (ping_callback_ref != LUA_NOREF) {
  fa:   f00d            ret.n

Disassembly of section .text.test_ping:

00000000 <test_ping-0x5c>:



and

Code: Select all
Disassembly of section .text.ping_by_hostname$part$0:

00000000 <ping_by_hostname$part$0-0xc>:


// test.identity() - takes a single value, returns it
static int test_identity(lua_State *L) { 
  return 1;
}
   0:   000046          j       5 <ping_by_hostname$part$0-0x7>
        ...

0000000c <ping_by_hostname$part$0>:
   c:   00a492          movi    a9, 0x400
   f:   f0c112          addi    a1, a1, -16
  12:   3109            s32i.n  a0, a1, 12
  14:   fffb31          l32r    a3, 0 <ping_by_hostname$part$0-0xc>
  17:   c01190          sub     a1, a1, a9
  1a:   012d            mov.n   a2, a1
  1c:   fffa01          l32r    a0, 4 <ping_by_hostname$part$0-0x8>
  1f:   0000c0          callx0  a0
  22:   012d            mov.n   a2, a1
  24:   fff901          l32r    a0, 8 <ping_by_hostname$part$0-0x4>
  27:   0000c0          callx0  a0
  2a:   00a492          movi    a9, 0x400
  2d:   119a            add.n   a1, a1, a9
  2f:   3108            l32i.n  a0, a1, 12
  31:   10c112          addi    a1, a1, 16
  34:   f00d            ret.n

Disassembly of section .text.ping_by_hostname:

00000000 <ping_by_hostname-0x18>:
   0:   000045          call0   8 <ping_by_hostname-0x10>
        ...
   f:   000c00          excw
  12:   000000          ill
  15:   000000          ill

00000018 <ping_by_hostname>:
  18:   f0c112          addi    a1, a1, -16
  1b:   21c9            s32i.n  a12, a1, 8
  1d:   03cd            mov.n   a12, a3
  1f:   fff831          l32r    a3, 0 <ping_by_hostname-0x18>
  22:   821c            movi.n  a2, 24
  24:   040c            movi.n  a4, 0
  26:   3109            s32i.n  a0, a1, 12
  28:   fff901          l32r    a0, c <ping_by_hostname-0xc>
  2b:   0000c0          callx0  a0
  2e:   0c38            l32i.n  a3, a12, 0
  30:   080366          bnei    a3, -1, 3c <ping_by_hostname+0x24>
  33:   fff701          l32r    a0, 10 <ping_by_hostname-0x8>
  36:   0000c0          callx0  a0
  39:   0005c6          j       54 <ping_by_hostname+0x3c>
  3c:   fff241          l32r    a4, 4 <ping_by_hostname-0x14>
  3f:   1239            s32i.n  a3, a2, 4
  41:   030c            movi.n  a3, 0
  43:   0448            l32i.n  a4, a4, 0
  45:   2239            s32i.n  a3, a2, 8
  47:   fff031          l32r    a3, 8 <ping_by_hostname-0x10>
  4a:   0249            s32i.n  a4, a2, 0
  4c:   3239            s32i.n  a3, a2, 12
  4e:   fff101          l32r    a0, 14 <ping_by_hostname-0x4>
  51:   0000c0          callx0  a0
  54:   3108            l32i.n  a0, a1, 12
  56:   21c8            l32i.n  a12, a1, 8
  58:   10c112          addi    a1, a1, 16
  5b:   f00d            ret.n
(END)



How do the addresses from the error message / the map file match to the addresses in the object file?
I have tried some basic hex offset calculations, but cannot get to a consistent result.

When I look to the adresses in the mapfile, they are only short (less than 0x20) after the adresses beneath my test module function names. When I look to the objudmp output, such short offsets would point to a trailer before each function which is not accompanied by my source code. Does this mean the error is not immediately caused by my source, but by some more complex causal chain? How can I break this apart?

Where can I find the explanation of the messages before reboot?
Can somebody recommend a concise primer on the debugging process along this path?

How do I get a profound knwoledge of the stuff that happens?
If I can't, I'm afraid I have to give up on the endeavour of porting an ethernet driver :-(
User avatar
By devsaurus
#61222
Epc1 is the program counter where the exception occured and excvaddr is the address accessed.


In your case the excvaddr is 0x00000000 and 0x00000008 which looks like dereferencing an invalid pointer. Maybe ping_received() is missing some checks for NULL pointers?

I'd search for in-depth information like the LoadProhibitedCause thingy in an Xtensa architecture documentation. Though I never actually did this nor needed it.

Regarding debugging possibilities - GDB should give you a better insight into the compiled code than the mapfile or an objdump:

Code: Select all$ xtensa-lx106-elf-gdb app/.output/eagle/debug/image/eagle.app.v6.out
GNU gdb (crosstool-NG 1.20.0) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-build_unknown-linux-gnu --target=xtensa-lx106-elf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/devsaurus/esp8266/nodemcu-firmware/app/.output/eagle/debug/image/eagle.app.v6.out...done.
(gdb) disass ping_received
User avatar
By marcelstoer
#61223
wjr wrote:Still struggling with git :|


I know it's just a side track but we have a section in our contributing guidelines as for how to work with Git and GitHub.