Skip to content

Commit

Permalink
gdbstub, postmortem: clean up
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
igrr committed Mar 9, 2018
1 parent 0643d6e commit 170911a
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 45 deletions.
7 changes: 1 addition & 6 deletions cores/esp8266/core_esp8266_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
Expand Down
59 changes: 24 additions & 35 deletions cores/esp8266/core_esp8266_postmortem.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,24 @@
#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;

// These will be pointers to PROGMEM const strings
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;
Expand All @@ -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 &&
Expand Down Expand Up @@ -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 );
Expand All @@ -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);
}
Expand All @@ -192,29 +180,30 @@ 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) {
(void) what;
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 changes: 36 additions & 0 deletions cores/esp8266/gdb_hooks.c
Original file line number Diff line number Diff line change
@@ -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 changes: 57 additions & 0 deletions cores/esp8266/gdb_hooks.h
Original file line number Diff line number Diff line change
@@ -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
2 changes: 0 additions & 2 deletions libraries/GDBStub/src/GDBStub.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,4 @@

// this header is intentionally left blank

bool crash_for_gdb = 1;

#endif //GDBSTUB_H
10 changes: 8 additions & 2 deletions libraries/GDBStub/src/internal/gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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")));

0 comments on commit 170911a

Please sign in to comment.