diff options
-rw-r--r-- | cmd/sbc_harness/config/config.h | 1 | ||||
-rw-r--r-- | cmd/srv9p/config/config.h | 1 | ||||
-rw-r--r-- | gdb-helpers/libcr.py | 32 | ||||
-rw-r--r-- | libcr/CMakeLists.txt | 1 | ||||
-rw-r--r-- | libcr/coroutine.c | 13 | ||||
-rw-r--r-- | libcr_ipc/tests/config.h | 1 |
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_ */ |