Skip to content

Commit 170911a

Browse files
committed
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
1 parent 0643d6e commit 170911a

File tree

6 files changed

+126
-45
lines changed

6 files changed

+126
-45
lines changed

cores/esp8266/core_esp8266_main.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ extern "C" {
3333
#include "cont.h"
3434
}
3535
#include <core_version.h>
36+
#include "gdb_hooks.h"
3637

3738
#define LOOP_TASK_PRIORITY 1
3839
#define LOOP_QUEUE_SIZE 1
@@ -137,12 +138,6 @@ static void do_global_ctors(void) {
137138
(*--p)();
138139
}
139140

140-
extern "C" void __gdb_init() {}
141-
extern "C" void gdb_init(void) __attribute__ ((weak, alias("__gdb_init")));
142-
143-
extern "C" void __gdb_do_break(){}
144-
extern "C" void gdb_do_break(void) __attribute__ ((weak, alias("__gdb_do_break")));
145-
146141
void init_done() {
147142
system_set_os_print(1);
148143
gdb_init();

cores/esp8266/core_esp8266_postmortem.c

+24-35
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,24 @@
2828
#include "esp8266_peri.h"
2929
#include "cont.h"
3030
#include "pgmspace.h"
31+
#include "gdb_hooks.h"
3132

3233
extern void __real_system_restart_local();
33-
extern void gdb_do_break();
3434

3535
extern cont_t g_cont;
3636

3737
// These will be pointers to PROGMEM const strings
3838
static const char* s_panic_file = 0;
3939
static int s_panic_line = 0;
4040
static const char* s_panic_func = 0;
41-
4241
static bool s_abort_called = false;
4342

44-
void uart_write_char_d(char c);
43+
void abort() __attribute__((noreturn));
44+
static void uart_write_char_d(char c);
4545
static void uart0_write_char_d(char c);
4646
static void uart1_write_char_d(char c);
4747
static void print_stack(uint32_t start, uint32_t end);
48-
//static void print_pcs(uint32_t start, uint32_t end);
49-
50-
bool __attribute((weak)) crash_for_gdb = 0;
48+
static void raise_exception() __attribute__((noreturn));
5149

5250
extern void __custom_crash_callback( struct rst_info * rst_info, uint32_t stack, uint32_t stack_end ) {
5351
(void) rst_info;
@@ -66,9 +64,17 @@ static void ets_puts_P(const char *romString) {
6664
}
6765

6866
void __wrap_system_restart_local() {
69-
if (crash_for_gdb) *((int*)0) = 0;
7067
register uint32_t sp asm("a1");
7168

69+
if (gdb_present()) {
70+
/* When GDBStub is present, exceptions are handled by GDBStub,
71+
but Soft WDT will still call this function.
72+
Trigger an exception to break into GDB.
73+
TODO: check why gdb_do_break() or asm("break.n 0") do not
74+
break into GDB here. */
75+
raise_exception();
76+
}
77+
7278
struct rst_info rst_info = {0};
7379
system_rtc_mem_read(0, &rst_info, sizeof(rst_info));
7480
if (rst_info.reason != REASON_SOFT_WDT_RST &&
@@ -129,7 +135,6 @@ void __wrap_system_restart_local() {
129135

130136
ets_printf("sp: %08x end: %08x offset: %04x\n", sp, stack_end, offset);
131137

132-
// print_pcs(sp + offset, stack_end);
133138
print_stack(sp + offset, stack_end);
134139

135140
custom_crash_callback( &rst_info, sp + offset, stack_end );
@@ -153,24 +158,7 @@ static void print_stack(uint32_t start, uint32_t end) {
153158
ets_puts_P(PSTR("<<<stack<<<\n"));
154159
}
155160

156-
/*
157-
static void print_pcs(uint32_t start, uint32_t end) {
158-
uint32_t n = 0;
159-
ets_printf("\n>>>pc>>>\n");
160-
for (uint32_t pos = start; pos < end; pos += 16, ++n) {
161-
uint32_t* sf = (uint32_t*) pos;
162-
163-
uint32_t pc_ret = sf[3];
164-
uint32_t sp_ret = sf[2];
165-
if (pc_ret < 0x40000000 || pc_ret > 0x40f00000 || sp_ret != pos + 16)
166-
continue;
167-
ets_printf("%08x\n", pc_ret);
168-
}
169-
ets_printf("<<<pc<<<\n");
170-
}
171-
*/
172-
173-
void uart_write_char_d(char c) {
161+
static void uart_write_char_d(char c) {
174162
uart0_write_char_d(c);
175163
uart1_write_char_d(c);
176164
}
@@ -192,29 +180,30 @@ static void uart1_write_char_d(char c) {
192180
}
193181
USF(1) = c;
194182
}
195-
void abort() __attribute__((noreturn));
196183

197-
void abort(){
198-
// cause exception
184+
static void raise_exception() {
185+
__asm__ __volatile__ ("syscall");
186+
while (1); // never reached, needed to satisfy "noreturn" attribute
187+
}
188+
189+
void abort() {
199190
s_abort_called = true;
200-
do {
201-
*((int*)0) = 0;
202-
} while(true);
191+
raise_exception();
203192
}
204193

205194
void __assert_func(const char *file, int line, const char *func, const char *what) {
206195
(void) what;
207196
s_panic_file = file;
208197
s_panic_line = line;
209198
s_panic_func = func;
210-
gdb_do_break();
199+
gdb_do_break(); /* if GDB is not present, this is a no-op */
211200
}
212201

213202
void __panic_func(const char* file, int line, const char* func) {
214203
s_panic_file = file;
215204
s_panic_line = line;
216205
s_panic_func = func;
217-
gdb_do_break();
218-
abort();
206+
gdb_do_break(); /* if GDB is not present, this is a no-op */
207+
raise_exception();
219208
}
220209

cores/esp8266/gdb_hooks.c

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
gdb_hooks.c - Default (no-op) hooks for GDB Stub library
3+
Copyright (c) 2018 Ivan Grokhotkov. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#include "ets_sys.h"
21+
#include "gdb_hooks.h"
22+
23+
24+
/* gdb_init and gdb_do_break do not return anything, but since the return
25+
value is in register, it doesn't hurt to return a bool, so that the
26+
same stub can be used for gdb_present. */
27+
28+
bool ICACHE_RAM_ATTR __gdb_no_op()
29+
{
30+
return false;
31+
}
32+
33+
extern void gdb_init(void) __attribute__ ((weak, alias("__gdb_no_op")));
34+
extern void gdb_do_break(void) __attribute__ ((weak, alias("__gdb_no_op")));
35+
extern bool gdb_present(void) __attribute__ ((weak, alias("__gdb_no_op")));
36+

cores/esp8266/gdb_hooks.h

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
gdb_hooks.h - Hooks for GDB Stub library
3+
Copyright (c) 2018 Ivan Grokhotkov. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#pragma once
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
/**
27+
* @brief Initialize GDB stub, if present
28+
*
29+
* By default, this function is a no-op. When GDBStub library is linked,
30+
* this function is overriden and does necessary initialization of that library.
31+
* Called early at startup.
32+
*/
33+
void gdb_init(void);
34+
35+
/**
36+
* @brief Break into GDB, if present
37+
*
38+
* By default, this function is a no-op. When GDBStub library is linked,
39+
* this function is overriden and triggers entry into the debugger, which
40+
* looks like a breakpoint hit.
41+
*/
42+
void gdb_do_break(void);
43+
44+
/**
45+
* @brief Check if GDB stub is present.
46+
*
47+
* By default, this function returns false. When GDBStub library is linked,
48+
* this function is overriden and returns true. Can be used to check whether
49+
* GDB is used.
50+
*
51+
* @return true if GDB stub is present
52+
*/
53+
bool gdb_present(void);
54+
55+
#ifdef __cplusplus
56+
}
57+
#endif

libraries/GDBStub/src/GDBStub.h

-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@
33

44
// this header is intentionally left blank
55

6-
bool crash_for_gdb = 1;
7-
86
#endif //GDBSTUB_H

libraries/GDBStub/src/internal/gdbstub.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -792,5 +792,11 @@ void ATTR_GDBFN gdbstub_do_break_wrapper() {
792792
gdbstub_do_break();
793793
}
794794

795-
extern void gdb_do_break() __attribute__((weak, alias("gdbstub_do_break_wrapper")));
796-
extern void gdb_init() __attribute__((weak, alias("gdbstub_init")));
795+
bool ATTR_GDBINIT gdb_present()
796+
{
797+
return true;
798+
}
799+
800+
extern void gdb_do_break() __attribute__((alias("gdbstub_do_break_wrapper")));
801+
extern void gdb_init() __attribute__((alias("gdbstub_init")));
802+

0 commit comments

Comments
 (0)