Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
e00d927a
Commit
e00d927a
authored
Feb 14, 2018
by
TerryE
Browse files
Tweaks to the Remote GDB interface to make it usable
parent
4141e690
Changes
5
Hide whitespace changes
Inline
Side-by-side
.gdbinit
0 → 100644
View file @
e00d927a
#
# This is very much a work in progress to show how we can use macros to make the
# GDB interface a lot more useable. For example the next / step commands only
# work if the stepper doesn't leave the current scope. Beyond that you have a
# single hardware breakpoint which can be used as an hb or a wa. You have to
# remember to delete the previous one, so the br macro does this for you.
#
set confirm off
set print null-stop
define br
d
hb $arg0
end
set pagination off
define prTV
if $arg0
set $type = $arg0.tt
set $val = $arg0.value
if $type == 0
# NIL
printf "Nil\n"
end
if $type == 1
# Boolean
printf "Boolean: %u\n", $val->n
end
if $type == 2
# ROTable
printf "ROTable: %p\n", $val->p
end
if $type == 3
# Light Function
printf "Light Func: %p\n",p $arg $val->p
end
if $type == 4
# Light User Data
printf "Light Udata: %p\n", $val->pend
end
if $type == 5
# Number
printf "Boolean: %u\n", $val->n
end
if $type == 6
# TString
set $o = &($val.gc->ts.tsv)
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
printf "String: hash = 0x%08x, len = %u : %s\n", $o->hash, $o->len, (char *)($ts+1)
end
if $type == 7
# Table
__printComHdr $arg0
set $ts = (TString *)$val->p
end
if $type == 8
# Function
set $o = &($val->gc.cl.c)
printf "Common header: next = %p, marked = 0x%01x\n", $o->next, $o->marked
if $o->isC == 0
set $o = &($val->gc.cl.l)
printf "LClosure: nupvalues = %u, gclist = %p, env = %p, p = %p\n", $o->nupvalues, $o->gclist, $o->env, $o->p
else
printf "CClosure: nupvalues = %u, gclist = %p, env = %p, f = %p\np", $o->nupvalues, $o->gclist, $o->env, $o->f
end
end
if $type == 9
# UserData
end
if $type == 10
# Thread
end
end
end
define prL
if L > 0
printf " stack: %u\n", L->top-L->base
printf " hooking: %u, %u, %u, %u, %p\n", L->hookmask, L->allowhook, L->basehookcount, L->hookcount, L->hook
end
end
define dumpstrt
set $st = $arg0
set $i = 0
while $i< $st->size
set $o = &(((TString *)($st->hash[$i]))->tsv)
while $o
if $o->next
printf "Slot: %5i %p %p %08x %02x %4u", $i, $o, $o->next, $o->hash, $o->marked, $o->len
else
printf "Slot: %5i %p %08x %02x %4u", $i, $o, $o->hash, $o->marked, $o->len
end
if $o->marked & 0x80
printf "* %s\n", *(char **)($o+1)
else
printf " %s\n", (char *)($o+1)
end
set $o = &(((TString *)($o->next))->tsv)
end
set $i = $i + 1
end
end
define dumpRAMstrt
dumpstrt &(L->l_G->strt)
end
set history save on
set history size 1000
app/include/user_config.h
View file @
e00d927a
...
@@ -12,11 +12,19 @@
...
@@ -12,11 +12,19 @@
// This adds the asserts in LUA. It also adds some useful extras to the
// This adds the asserts in LUA. It also adds some useful extras to the
// node module. This is all silent in normal operation and so can be enabled
// node module. This is all silent in normal operation and so can be enabled
// without any harm (except for the code size increase and slight slowdown)
// without any harm (except for the code size increase and slight slowdown)
// Either here for a global change or in the DEFINES variable in the relevant
// Makefile for ony one subdirectory. If you want to use the remote GDB to
// handle breaks and failed assetions then enable DEVELOPMENT_USE GDB
//#define DEVELOPMENT_TOOLS
//#define DEVELOPMENT_TOOLS
//#define DEVELOPMENT_USE_GDB
#ifdef DEVELOPMENT_TOOLS
#ifdef DEVELOPMENT_TOOLS
#if defined(LUA_CROSS_COMPILER) || !defined(DEVELOPMENT_USE_GDB)
extern
void
luaL_assertfail
(
const
char
*
file
,
int
line
,
const
char
*
message
);
extern
void
luaL_assertfail
(
const
char
*
file
,
int
line
,
const
char
*
message
);
#define lua_assert(x) ((x) ? (void) 0 : luaL_assertfail(__FILE__, __LINE__, #x))
#define lua_assert(x) ((x) ? (void) 0 : luaL_assertfail(__FILE__, __LINE__, #x))
#else
extern
void
luaL_dbgbreak
(
void
);
#define lua_assert(x) ((x) ? (void) 0 : luaL_dbgbreak())
#endif
#endif
#endif
// This enables lots of debug output and changes the serial bit rate. This
// This enables lots of debug output and changes the serial bit rate. This
...
...
app/lua/lauxlib.c
View file @
e00d927a
...
@@ -44,6 +44,101 @@
...
@@ -44,6 +44,101 @@
#define LUA_USECCLOSURES 0
#define LUA_USECCLOSURES 0
#define LUA_USELIGHTFUNCTIONS 1
#define LUA_USELIGHTFUNCTIONS 1
//#define DEBUG_ALLOCATOR
#ifdef DEBUG_ALLOCATOR
/*
** {======================================================================
** Diagnosticd version for realloc. This is enabled only if the
** DEBUG_ALLOCATOR is defined. It is a cutdown version of the allocator
** used in the Lua Test Suite -- a compromise between the ability catch
** most alloc/free errors and overruns and working within the RAM limits
** of the ESP8266 architecture. ONLY FOR HEAVY HACKERS
** =======================================================================
*/
#define this_realloc debug_realloc
#define ASSERT(s) if (!(s)) {asm ("break 0,0" ::);}
#define MARK 0x55
/* 01010101 (a nice pattern) */
#define MARK4 0x55555555
#define MARKSIZE 4
/* size of marks after each block */
#define fillmem(mem,size) memset(mem, -MARK, size)
typedef
struct
Memcontrol
{
/* memory-allocator control variables */
uint32_t
numblocks
;
uint32_t
total
;
uint32_t
maxmem
;
uint32_t
memlimit
;
}
Memcontrol
;
static
Memcontrol
mc
=
{
0
,
0
,
0
,
32768
};
typedef
union
MemHeader
{
L_Umaxalign
a
;
/* ensures maximum alignment for Header */
struct
{
size_t
size
;
int
mark
;
}
d
;
}
MemHeader
;
static
void
freeblock
(
MemHeader
*
block
)
{
if
(
block
)
{
size_t
size
=
block
->
d
.
size
;
fillmem
(
block
,
sizeof
(
MemHeader
)
+
size
+
MARKSIZE
);
/* erase block */
c_free
(
block
);
/* actually free block */
mc
.
numblocks
--
;
/* update counts */
mc
.
total
-=
size
;
}
}
void
*
debug_realloc
(
void
*
b
,
size_t
oldsize
,
size_t
size
)
{
MemHeader
*
block
=
cast
(
MemHeader
*
,
b
);
int
i
;
if
(
block
==
NULL
)
{
oldsize
=
0
;
}
else
{
block
--
;
/* go to real header */
ASSERT
(
block
->
d
.
mark
==
MARK4
);
ASSERT
(
oldsize
==
block
->
d
.
size
);
for
(
i
=
0
;
i
<
MARKSIZE
;
i
++
)
/* check marks after block */
ASSERT
(
cast
(
char
*
,
b
)[
oldsize
+
i
]
==
MARK
);
}
if
(
size
==
0
)
{
freeblock
(
block
);
return
NULL
;
}
else
if
(
size
>
oldsize
&&
mc
.
total
+
size
-
oldsize
>
mc
.
memlimit
)
return
NULL
;
/* fake a memory allocation error */
else
{
MemHeader
*
newblock
;
int
i
;
size_t
commonsize
=
(
oldsize
<
size
)
?
oldsize
:
size
;
size_t
realsize
=
sizeof
(
MemHeader
)
+
size
+
MARKSIZE
;
newblock
=
cast
(
MemHeader
*
,
c_malloc
(
realsize
));
/* alloc a new block */
if
(
newblock
==
NULL
)
return
NULL
;
/* really out of memory? */
if
(
block
)
{
memcpy
(
newblock
+
1
,
block
+
1
,
commonsize
);
/* copy old contents */
freeblock
(
block
);
/* erase (and check) old copy */
}
/* initialize new part of the block with something weird */
fillmem
(
cast
(
char
*
,
newblock
+
1
)
+
commonsize
,
size
-
commonsize
);
/* initialize marks after block */
newblock
->
d
.
mark
=
MARK4
;
newblock
->
d
.
size
=
size
;
for
(
i
=
0
;
i
<
MARKSIZE
;
i
++
)
cast
(
char
*
,
newblock
+
1
)[
size
+
i
]
=
MARK
;
mc
.
total
+=
size
;
if
(
mc
.
total
>
mc
.
maxmem
)
mc
.
maxmem
=
mc
.
total
;
mc
.
numblocks
++
;
return
(
newblock
+
1
);
}
}
/* }====================================================================== */
#else
#define this_realloc(p,os,s) c_realloc(p,s)
#endif
/*
/*
** {======================================================
** {======================================================
** Error-report functions
** Error-report functions
...
@@ -786,8 +881,12 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
...
@@ -786,8 +881,12 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
void
*
nptr
;
void
*
nptr
;
if
(
nsize
==
0
)
{
if
(
nsize
==
0
)
{
#ifdef DEBUG_ALLOCATOR
return
(
void
*
)
this_realloc
(
ptr
,
osize
,
nsize
);
#else
c_free
(
ptr
);
c_free
(
ptr
);
return
NULL
;
return
NULL
;
#endif
}
}
if
(
L
!=
NULL
&&
(
mode
&
EGC_ALWAYS
))
/* always collect memory if requested */
if
(
L
!=
NULL
&&
(
mode
&
EGC_ALWAYS
))
/* always collect memory if requested */
luaC_fullgc
(
L
);
luaC_fullgc
(
L
);
...
@@ -798,18 +897,45 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
...
@@ -798,18 +897,45 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
if
(
G
(
L
)
->
memlimit
>
0
&&
(
mode
&
EGC_ON_MEM_LIMIT
)
&&
l_check_memlimit
(
L
,
nsize
-
osize
))
if
(
G
(
L
)
->
memlimit
>
0
&&
(
mode
&
EGC_ON_MEM_LIMIT
)
&&
l_check_memlimit
(
L
,
nsize
-
osize
))
return
NULL
;
return
NULL
;
}
}
nptr
=
(
void
*
)
c
_realloc
(
ptr
,
nsize
);
nptr
=
(
void
*
)
this
_realloc
(
ptr
,
osize
,
nsize
);
if
(
nptr
==
NULL
&&
L
!=
NULL
&&
(
mode
&
EGC_ON_ALLOC_FAILURE
))
{
if
(
nptr
==
NULL
&&
L
!=
NULL
&&
(
mode
&
EGC_ON_ALLOC_FAILURE
))
{
luaC_fullgc
(
L
);
/* emergency full collection. */
luaC_fullgc
(
L
);
/* emergency full collection. */
nptr
=
(
void
*
)
c
_realloc
(
ptr
,
nsize
);
/* try allocation again */
nptr
=
(
void
*
)
this
_realloc
(
ptr
,
osize
,
nsize
);
/* try allocation again */
}
}
return
nptr
;
return
nptr
;
}
}
LUALIB_API
void
luaL_assertfail
(
const
char
*
file
,
int
line
,
const
char
*
message
)
{
LUALIB_API
void
luaL_assertfail
(
const
char
*
file
,
int
line
,
const
char
*
message
)
{
dbg_printf
(
"ASSERT@%s(%d): %s
\n
"
,
file
,
line
,
message
);
dbg_printf
(
"ASSERT@%s(%d): %s
\n
"
,
file
,
line
,
message
);
#if defined(LUA_CROSS_COMPILER)
exit
(
1
);
#endif
}
}
#ifdef DEVELOPMENT_USE_GDB
/*
* This is a simple stub used by lua_assert() if DEVELOPMENT_USE_GDB is defined.
* Instead of crashing out with an assert error, this hook starts the GDB remote
* stub if not already running and then issues a break. The rationale here is
* that when testing the developer migght be using screen/PuTTY to work ineractively
* with the Lua Interpreter via UART0. However if an assert triggers, then there
* is the option to exit the interactive session and start the Xtensa remote GDB
* which will then sync up with the remote GDB client to allow forensics of the error.
*/
extern
void
gdbstub_init
(
void
);
LUALIB_API
void
luaL_dbgbreak
(
void
)
{
static
int
repeat_entry
=
0
;
if
(
repeat_entry
==
0
)
{
dbg_printf
(
"Start up the gdb stub if not already started
\n
"
);
gdbstub_init
();
repeat_entry
=
1
;
}
asm
(
"break 0,0"
::
);
}
#endif
static
int
panic
(
lua_State
*
L
)
{
static
int
panic
(
lua_State
*
L
)
{
(
void
)
L
;
/* to avoid warnings */
(
void
)
L
;
/* to avoid warnings */
#if defined(LUA_USE_STDIO)
#if defined(LUA_USE_STDIO)
...
...
app/modules/gdbstub.c
View file @
e00d927a
...
@@ -2,7 +2,8 @@
...
@@ -2,7 +2,8 @@
* This module, when enabled with the LUA_USE_MODULES_GDBSTUB define causes
* This module, when enabled with the LUA_USE_MODULES_GDBSTUB define causes
* the gdbstub code to be included and enabled to handle all fatal exceptions.
* the gdbstub code to be included and enabled to handle all fatal exceptions.
* This allows you to use the lx106 gdb to catch the exception and then poke
* This allows you to use the lx106 gdb to catch the exception and then poke
* around. You can't continue from an exception (at least not easily).
* around. You can continue from a break, but attempting to continue from an
* exception usually fails.
*
*
* This should not be included in production builds as any exception will
* This should not be included in production builds as any exception will
* put the nodemcu into a state where it is waiting for serial input and it has
* put the nodemcu into a state where it is waiting for serial input and it has
...
@@ -41,8 +42,8 @@ static int lgdbstub_open(lua_State *L) {
...
@@ -41,8 +42,8 @@ static int lgdbstub_open(lua_State *L) {
static
const
LUA_REG_TYPE
gdbstub_map
[]
=
{
static
const
LUA_REG_TYPE
gdbstub_map
[]
=
{
{
LSTRKEY
(
"brk"
),
LFUNCVAL
(
lgdbstub_break
)
},
{
LSTRKEY
(
"brk"
),
LFUNCVAL
(
lgdbstub_break
)
},
{
LSTRKEY
(
"gdboutput"
),
LFUNCVAL
(
lgdbstub_gdboutput
)
},
{
LSTRKEY
(
"gdboutput"
),
LFUNCVAL
(
lgdbstub_gdboutput
)
},
{
LSTRKEY
(
"open"
),
LFUNCVAL
(
lgdbstub_open
)
},
{
LNILKEY
,
LNILVAL
}
{
LNILKEY
,
LNILVAL
}
};
};
NODEMCU_MODULE
(
GDBSTUB
,
"gdbstub"
,
gdbstub_map
,
lgdbstub_open
);
NODEMCU_MODULE
(
GDBSTUB
,
"gdbstub"
,
gdbstub_map
,
NULL
);
app/user/user_exceptions.c
View file @
e00d927a
...
@@ -40,7 +40,6 @@
...
@@ -40,7 +40,6 @@
static
exception_handler_fn
load_store_handler
;
static
exception_handler_fn
load_store_handler
;
void
load_non_32_wide_handler
(
struct
exception_frame
*
ef
,
uint32_t
cause
)
void
load_non_32_wide_handler
(
struct
exception_frame
*
ef
,
uint32_t
cause
)
{
{
/* If this is not EXCCAUSE_LOAD_STORE_ERROR you're doing it wrong! */
/* If this is not EXCCAUSE_LOAD_STORE_ERROR you're doing it wrong! */
...
@@ -73,13 +72,15 @@ void load_non_32_wide_handler (struct exception_frame *ef, uint32_t cause)
...
@@ -73,13 +72,15 @@ void load_non_32_wide_handler (struct exception_frame *ef, uint32_t cause)
{
{
die:
die:
/* Turns out we couldn't fix this, so try and chain to the handler
/* Turns out we couldn't fix this, so try and chain to the handler
* that was set by the SDK. If none then trigger a system break instead
* that was set. (This is typically a remote GDB break). If none
* and hang if the break doesn't get handled. This is effectively
* then trigger a system break instead and hang if the break doesn't
* what would happen if the default handler was installed. */
* get handled. This is effectively what would happen if the default
* handler was installed. */
if
(
load_store_handler
)
{
if
(
load_store_handler
)
{
load_store_handler
(
ef
,
cause
);
load_store_handler
(
ef
,
cause
);
return
;
}
}
asm
(
"break 1, 1"
);
asm
(
"break 1, 1"
);
while
(
1
)
{}
while
(
1
)
{}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment