mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-25 20:02:37 +03:00
gdbstub, postmortem: clean up
- Move GDB stub hooks into a separate file, provide header for it - Use syscall instruction raise user mode exception - Remove unused code in postmortem.c fixup fixup
This commit is contained in:
parent
0643d6e7ab
commit
170911a689
@ -33,6 +33,7 @@ extern "C" {
|
||||
#include "cont.h"
|
||||
}
|
||||
#include <core_version.h>
|
||||
#include "gdb_hooks.h"
|
||||
|
||||
#define LOOP_TASK_PRIORITY 1
|
||||
#define LOOP_QUEUE_SIZE 1
|
||||
@ -137,12 +138,6 @@ static void do_global_ctors(void) {
|
||||
(*--p)();
|
||||
}
|
||||
|
||||
extern "C" void __gdb_init() {}
|
||||
extern "C" void gdb_init(void) __attribute__ ((weak, alias("__gdb_init")));
|
||||
|
||||
extern "C" void __gdb_do_break(){}
|
||||
extern "C" void gdb_do_break(void) __attribute__ ((weak, alias("__gdb_do_break")));
|
||||
|
||||
void init_done() {
|
||||
system_set_os_print(1);
|
||||
gdb_init();
|
||||
|
@ -28,9 +28,9 @@
|
||||
#include "esp8266_peri.h"
|
||||
#include "cont.h"
|
||||
#include "pgmspace.h"
|
||||
#include "gdb_hooks.h"
|
||||
|
||||
extern void __real_system_restart_local();
|
||||
extern void gdb_do_break();
|
||||
|
||||
extern cont_t g_cont;
|
||||
|
||||
@ -38,16 +38,14 @@ extern cont_t g_cont;
|
||||
static const char* s_panic_file = 0;
|
||||
static int s_panic_line = 0;
|
||||
static const char* s_panic_func = 0;
|
||||
|
||||
static bool s_abort_called = false;
|
||||
|
||||
void uart_write_char_d(char c);
|
||||
void abort() __attribute__((noreturn));
|
||||
static void uart_write_char_d(char c);
|
||||
static void uart0_write_char_d(char c);
|
||||
static void uart1_write_char_d(char c);
|
||||
static void print_stack(uint32_t start, uint32_t end);
|
||||
//static void print_pcs(uint32_t start, uint32_t end);
|
||||
|
||||
bool __attribute((weak)) crash_for_gdb = 0;
|
||||
static void raise_exception() __attribute__((noreturn));
|
||||
|
||||
extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) {
|
||||
(void) rst_info;
|
||||
@ -66,9 +64,17 @@ static void ets_puts_P(const char *romString) {
|
||||
}
|
||||
|
||||
void __wrap_system_restart_local() {
|
||||
if (crash_for_gdb) *((int*)0) = 0;
|
||||
register uint32_t sp asm("a1");
|
||||
|
||||
if (gdb_present()) {
|
||||
/* When GDBStub is present, exceptions are handled by GDBStub,
|
||||
but Soft WDT will still call this function.
|
||||
Trigger an exception to break into GDB.
|
||||
TODO: check why gdb_do_break() or asm("break.n 0") do not
|
||||
break into GDB here. */
|
||||
raise_exception();
|
||||
}
|
||||
|
||||
struct rst_info rst_info = {0};
|
||||
system_rtc_mem_read(0, &rst_info, sizeof(rst_info));
|
||||
if (rst_info.reason != REASON_SOFT_WDT_RST &&
|
||||
@ -129,7 +135,6 @@ void __wrap_system_restart_local() {
|
||||
|
||||
ets_printf("sp: %08x end: %08x offset: %04x\n", sp, stack_end, offset);
|
||||
|
||||
// print_pcs(sp + offset, stack_end);
|
||||
print_stack(sp + offset, stack_end);
|
||||
|
||||
custom_crash_callback( &rst_info, sp + offset, stack_end );
|
||||
@ -153,24 +158,7 @@ static void print_stack(uint32_t start, uint32_t end) {
|
||||
ets_puts_P(PSTR("<<<stack<<<\n"));
|
||||
}
|
||||
|
||||
/*
|
||||
static void print_pcs(uint32_t start, uint32_t end) {
|
||||
uint32_t n = 0;
|
||||
ets_printf("\n>>>pc>>>\n");
|
||||
for (uint32_t pos = start; pos < end; pos += 16, ++n) {
|
||||
uint32_t* sf = (uint32_t*) pos;
|
||||
|
||||
uint32_t pc_ret = sf[3];
|
||||
uint32_t sp_ret = sf[2];
|
||||
if (pc_ret < 0x40000000 || pc_ret > 0x40f00000 || sp_ret != pos + 16)
|
||||
continue;
|
||||
ets_printf("%08x\n", pc_ret);
|
||||
}
|
||||
ets_printf("<<<pc<<<\n");
|
||||
}
|
||||
*/
|
||||
|
||||
void uart_write_char_d(char c) {
|
||||
static void uart_write_char_d(char c) {
|
||||
uart0_write_char_d(c);
|
||||
uart1_write_char_d(c);
|
||||
}
|
||||
@ -192,14 +180,15 @@ static void uart1_write_char_d(char c) {
|
||||
}
|
||||
USF(1) = c;
|
||||
}
|
||||
void abort() __attribute__((noreturn));
|
||||
|
||||
void abort(){
|
||||
// cause exception
|
||||
static void raise_exception() {
|
||||
__asm__ __volatile__ ("syscall");
|
||||
while (1); // never reached, needed to satisfy "noreturn" attribute
|
||||
}
|
||||
|
||||
void abort() {
|
||||
s_abort_called = true;
|
||||
do {
|
||||
*((int*)0) = 0;
|
||||
} while(true);
|
||||
raise_exception();
|
||||
}
|
||||
|
||||
void __assert_func(const char *file, int line, const char *func, const char *what) {
|
||||
@ -207,14 +196,14 @@ void __assert_func(const char *file, int line, const char *func, const char *wha
|
||||
s_panic_file = file;
|
||||
s_panic_line = line;
|
||||
s_panic_func = func;
|
||||
gdb_do_break();
|
||||
gdb_do_break(); /* if GDB is not present, this is a no-op */
|
||||
}
|
||||
|
||||
void __panic_func(const char* file, int line, const char* func) {
|
||||
s_panic_file = file;
|
||||
s_panic_line = line;
|
||||
s_panic_func = func;
|
||||
gdb_do_break();
|
||||
abort();
|
||||
gdb_do_break(); /* if GDB is not present, this is a no-op */
|
||||
raise_exception();
|
||||
}
|
||||
|
||||
|
36
cores/esp8266/gdb_hooks.c
Normal file
36
cores/esp8266/gdb_hooks.c
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
gdb_hooks.c - Default (no-op) hooks for GDB Stub library
|
||||
Copyright (c) 2018 Ivan Grokhotkov. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "gdb_hooks.h"
|
||||
|
||||
|
||||
/* gdb_init and gdb_do_break do not return anything, but since the return
|
||||
value is in register, it doesn't hurt to return a bool, so that the
|
||||
same stub can be used for gdb_present. */
|
||||
|
||||
bool ICACHE_RAM_ATTR __gdb_no_op()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
extern void gdb_init(void) __attribute__ ((weak, alias("__gdb_no_op")));
|
||||
extern void gdb_do_break(void) __attribute__ ((weak, alias("__gdb_no_op")));
|
||||
extern bool gdb_present(void) __attribute__ ((weak, alias("__gdb_no_op")));
|
||||
|
57
cores/esp8266/gdb_hooks.h
Normal file
57
cores/esp8266/gdb_hooks.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
gdb_hooks.h - Hooks for GDB Stub library
|
||||
Copyright (c) 2018 Ivan Grokhotkov. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize GDB stub, if present
|
||||
*
|
||||
* By default, this function is a no-op. When GDBStub library is linked,
|
||||
* this function is overriden and does necessary initialization of that library.
|
||||
* Called early at startup.
|
||||
*/
|
||||
void gdb_init(void);
|
||||
|
||||
/**
|
||||
* @brief Break into GDB, if present
|
||||
*
|
||||
* By default, this function is a no-op. When GDBStub library is linked,
|
||||
* this function is overriden and triggers entry into the debugger, which
|
||||
* looks like a breakpoint hit.
|
||||
*/
|
||||
void gdb_do_break(void);
|
||||
|
||||
/**
|
||||
* @brief Check if GDB stub is present.
|
||||
*
|
||||
* By default, this function returns false. When GDBStub library is linked,
|
||||
* this function is overriden and returns true. Can be used to check whether
|
||||
* GDB is used.
|
||||
*
|
||||
* @return true if GDB stub is present
|
||||
*/
|
||||
bool gdb_present(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -3,6 +3,4 @@
|
||||
|
||||
// this header is intentionally left blank
|
||||
|
||||
bool crash_for_gdb = 1;
|
||||
|
||||
#endif //GDBSTUB_H
|
||||
|
@ -792,5 +792,11 @@ void ATTR_GDBFN gdbstub_do_break_wrapper() {
|
||||
gdbstub_do_break();
|
||||
}
|
||||
|
||||
extern void gdb_do_break() __attribute__((weak, alias("gdbstub_do_break_wrapper")));
|
||||
extern void gdb_init() __attribute__((weak, alias("gdbstub_init")));
|
||||
bool ATTR_GDBINIT gdb_present()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
extern void gdb_do_break() __attribute__((alias("gdbstub_do_break_wrapper")));
|
||||
extern void gdb_init() __attribute__((alias("gdbstub_init")));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user