summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/sbc_harness/config/config.h1
-rw-r--r--cmd/srv9p/config/config.h1
-rw-r--r--gdb-helpers/libcr.py32
-rw-r--r--libcr/CMakeLists.txt1
-rw-r--r--libcr/coroutine.c13
-rw-r--r--libcr_ipc/tests/config.h1
6 files changed, 38 insertions, 11 deletions
diff --git a/cmd/sbc_harness/config/config.h b/cmd/sbc_harness/config/config.h
index 85170cc..3a75c14 100644
--- a/cmd/sbc_harness/config/config.h
+++ b/cmd/sbc_harness/config/config.h
@@ -78,6 +78,7 @@
#define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */
#define CONFIG_COROUTINE_DEBUG 0 /* bool */
#define CONFIG_COROUTINE_VALGRIND 0 /* bool */
+#define CONFIG_COROUTINE_GDB 1 /* bool */
#define _CONFIG_9P_NUM_SOCKS 7
#define CONFIG_COROUTINE_NUM ( \
diff --git a/cmd/srv9p/config/config.h b/cmd/srv9p/config/config.h
index 82be297..4f8384e 100644
--- a/cmd/srv9p/config/config.h
+++ b/cmd/srv9p/config/config.h
@@ -51,6 +51,7 @@
#define CONFIG_COROUTINE_PROTECT_STACK 1 /* bool */
#define CONFIG_COROUTINE_DEBUG 0 /* bool */
#define CONFIG_COROUTINE_VALGRIND 1 /* bool */
+#define CONFIG_COROUTINE_GDB 1 /* bool */
#define CONFIG_COROUTINE_NUM (1 /* usb_common */ +\
1 /* usb_keyboard */ +\
CONFIG_SRV9P_NUM_CONNS /* accept+read */ +\
diff --git a/gdb-helpers/libcr.py b/gdb-helpers/libcr.py
index 0509387..dbe7ec8 100644
--- a/gdb-helpers/libcr.py
+++ b/gdb-helpers/libcr.py
@@ -71,6 +71,12 @@ class CrGlobals:
self.coroutines = [CrCoroutine(self, i + 1) for i in range(num)]
self.breakpoints = []
+ def delete(self) -> None:
+ self.coroutines = []
+ for b in self.breakpoints:
+ b.delete()
+ self.breakpoints = []
+
def is_valid_cid(self, cid: int) -> bool:
return 0 < cid and cid <= len(self.coroutines)
@@ -127,19 +133,26 @@ class CrCoroutine:
gdb_longjmp(saved_env)
-class CrYieldBreakpoint(gdb.Breakpoint):
+class CrSetJmpBreakpoint(gdb.Breakpoint):
cr_globals: CrGlobals
- def __init__(self, cr_globals: CrGlobals, function: str) -> None:
+ def __init__(self, cr_globals: CrGlobals) -> None:
self.cr_globals = cr_globals
cr_globals.breakpoints += [self]
- super().__init__(function=function, type=gdb.BP_BREAKPOINT, internal=True) # type: ignore
+ super().__init__(function="_cr_plat_setjmp_pre", type=gdb.BP_BREAKPOINT, internal=True) # type: ignore
def stop(self) -> bool:
- if self.cr_globals.is_valid_cid(self.cr_globals.coroutine_running):
- self.cr_globals.coroutines[self.cr_globals.coroutine_running - 1].env = (
- gdb_setjmp()
+ if bool(gdb.parse_and_eval("env == &coroutine_add_env")):
+ cid = self.cr_globals.coroutine_running
+ elif bool(gdb.parse_and_eval("env == &coroutine_main_env")):
+ cid = 0
+ else:
+ idx = gdb.parse_and_eval(
+ "( ((char*)env)-((char *)&coroutine_table)) / sizeof(coroutine_table[0])"
)
+ cid = int(idx) + 1
+ if self.cr_globals.is_valid_cid(cid):
+ self.cr_globals.coroutines[cid - 1].env = gdb_setjmp()
return False
@@ -255,9 +268,7 @@ class CrApplyCommand(gdb.Command):
def cr_initialize() -> None:
cr_globals = CrGlobals()
- CrYieldBreakpoint(cr_globals, "_cr_yield")
- CrYieldBreakpoint(cr_globals, "cr_begin")
- CrYieldBreakpoint(cr_globals, "coroutine_add_with_stack_size")
+ CrSetJmpBreakpoint(cr_globals)
CrCommand(cr_globals)
CrListCommand(cr_globals)
@@ -266,7 +277,8 @@ def cr_initialize() -> None:
def cr_on_new_objfile(event: gdb.Event) -> None:
if any(
- objfile.lookup_static_symbol("cr_plat_longjmp") for objfile in gdb.objfiles()
+ objfile.lookup_static_symbol("_cr_plat_setjmp_pre")
+ for objfile in gdb.objfiles()
):
print("Initializing libcr integration...")
cr_initialize()
diff --git a/libcr/CMakeLists.txt b/libcr/CMakeLists.txt
index 7f18e17..130b018 100644
--- a/libcr/CMakeLists.txt
+++ b/libcr/CMakeLists.txt
@@ -20,6 +20,7 @@ set(cfg_matrix
"CONFIG_COROUTINE_PROTECT_STACK;[0;1]"
"CONFIG_COROUTINE_DEBUG;[0;1]"
"CONFIG_COROUTINE_VALGRIND;[0;1]"
+ "CONFIG_COROUTINE_GDB;[0;1]"
)
function(add_libcr_matrix_test n defs)
add_executable("test_matrix${n}" "tests/test_matrix.c")
diff --git a/libcr/coroutine.c b/libcr/coroutine.c
index 18b2b80..a4d41e8 100644
--- a/libcr/coroutine.c
+++ b/libcr/coroutine.c
@@ -42,6 +42,9 @@
#ifndef CONFIG_COROUTINE_VALGRIND
#error config.h must define CONFIG_COROUTINE_VALGRIND (bool)
#endif
+#ifndef CONFIG_COROUTINE_GDB
+ #error config.h must define CONFIG_COROUTINE_GDB (bool)
+#endif
/* Implementation *************************************************************/
@@ -127,6 +130,7 @@
*/
#define ALWAYS_INLINE [[gnu::always_inline]] inline
+#define NEVER_INLINE [[gnu::noinline]]
/* platform support ***********************************************************/
@@ -314,7 +318,14 @@
uintptr_t sp;
#endif
} cr_plat_jmp_buf;
- static inline void _cr_plat_setjmp_pre(cr_plat_jmp_buf *env [[gnu::unused]]) {
+ #if CONIG_COROUTINE_GDB
+ NEVER_INLINE
+ #endif
+ static void _cr_plat_setjmp_pre(cr_plat_jmp_buf *env [[gnu::unused]]) {
+ #if CONIG_COROUTINE_GDB
+ /* Prevent the call from being optimized away. */
+ asm ("");
+ #endif
#if CONFIG_COROUTINE_MEASURE_STACK
env->sp = cr_plat_get_sp();
#endif
diff --git a/libcr_ipc/tests/config.h b/libcr_ipc/tests/config.h
index 949a82f..e06c876 100644
--- a/libcr_ipc/tests/config.h
+++ b/libcr_ipc/tests/config.h
@@ -15,5 +15,6 @@
#define CONFIG_COROUTINE_PROTECT_STACK 1
#define CONFIG_COROUTINE_DEBUG 1
#define CONFIG_COROUTINE_VALGRIND 1
+#define CONFIG_COROUTINE_GDB 1
#endif /* _CONFIG_H_ */