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
"vscode:/vscode.git/clone" did not exist on "67027c0d05f7e8d1b97104e05a3715f6ebc8d07f"
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