diff --git a/trunk/3rdparty/st-srs/README.md b/trunk/3rdparty/st-srs/README.md index 72e8b985e..625aa4662 100644 --- a/trunk/3rdparty/st-srs/README.md +++ b/trunk/3rdparty/st-srs/README.md @@ -116,6 +116,8 @@ The branch [srs](https://github.com/ossrs/state-threads/tree/srs) was patched an - [x] AppleM1: Support Apple Silicon M1(aarch64), [#30](https://github.com/ossrs/state-threads/issues/30). - [x] IDE: Support CLion for debugging and learning. - [x] Define and use a new jmpbuf, because the structure is different. +- [x] Check capability for backtrack. +- [x] Support set specifics for any thread. - [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12). ## GDB Tools diff --git a/trunk/3rdparty/st-srs/ide/st_clion/CMakeLists.txt b/trunk/3rdparty/st-srs/ide/st_clion/CMakeLists.txt index 9066b3b30..d54d8d3b4 100644 --- a/trunk/3rdparty/st-srs/ide/st_clion/CMakeLists.txt +++ b/trunk/3rdparty/st-srs/ide/st_clion/CMakeLists.txt @@ -48,6 +48,7 @@ IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") list(APPEND SOURCE_FILES ${ST_DIR}/md_darwin.S) ELSE () list(APPEND SOURCE_FILES ${ST_DIR}/md_linux.S) + list(APPEND SOURCE_FILES ${ST_DIR}/md_linux2.S) ENDIF () ADD_DEFINITIONS("-g -O0") @@ -66,6 +67,63 @@ TARGET_LINK_LIBRARIES(st_utest dl) TARGET_LINK_LIBRARIES(st_utest ${DEPS_LIBS}) TARGET_LINK_LIBRARIES(st_utest -ldl -pthread) +########################################################### +# Setup tools/backtrace project +set(ST_BACKTRACE_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/backtrace ST_BACKTRACE_SOURCE_FILES) + +ADD_EXECUTABLE(st_backtrace ${ST_BACKTRACE_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_backtrace ${DEPS_LIBS}) +TARGET_LINK_LIBRARIES(st_backtrace -ldl) + +########################################################### +# Setup tools/helloworld project +set(ST_HELLOWORLD_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/helloworld ST_HELLOWORLD_SOURCE_FILES) + +ADD_EXECUTABLE(st_helloworld ${ST_HELLOWORLD_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_helloworld ${DEPS_LIBS}) + +########################################################### +# Setup tools/jmpbuf project +set(ST_JMPBUF_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/jmpbuf ST_JMPBUF_SOURCE_FILES) + +ADD_EXECUTABLE(st_jmpbuf ${ST_JMPBUF_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_jmpbuf ${DEPS_LIBS}) + +########################################################### +# Setup tools/pcs project +set(ST_PCS_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/pcs ST_PCS_SOURCE_FILES) + +ADD_EXECUTABLE(st_pcs ${ST_PCS_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_pcs ${DEPS_LIBS}) + +########################################################### +# Setup tools/porting project +set(ST_PORTING_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/porting ST_PORTING_SOURCE_FILES) + +ADD_EXECUTABLE(st_porting ${ST_PORTING_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_porting ${DEPS_LIBS}) + +########################################################### +# Setup tools/stack project +set(ST_STACK_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/stack ST_STACK_SOURCE_FILES) + +ADD_EXECUTABLE(st_stack ${ST_STACK_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_stack ${DEPS_LIBS}) + +########################################################### +# Setup tools/verify project +set(ST_VERIFY_SOURCE_FILES ${SOURCE_FILES}) +AUX_SOURCE_DIRECTORY(${ST_DIR}/tools/verify ST_VERIFY_SOURCE_FILES) + +ADD_EXECUTABLE(st_verify ${ST_VERIFY_SOURCE_FILES}) +TARGET_LINK_LIBRARIES(st_verify ${DEPS_LIBS}) + ########################################################### # Done MESSAGE(STATUS "@see https://github.com/ossrs/state-threads#usage") diff --git a/trunk/3rdparty/st-srs/tools/backtrace/.gitignore b/trunk/3rdparty/st-srs/tools/backtrace/.gitignore new file mode 100644 index 000000000..f587f481c --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/backtrace/.gitignore @@ -0,0 +1 @@ +backtrace \ No newline at end of file diff --git a/trunk/3rdparty/st-srs/tools/backtrace/Makefile b/trunk/3rdparty/st-srs/tools/backtrace/Makefile new file mode 100644 index 000000000..e0780c5f7 --- /dev/null +++ b/trunk/3rdparty/st-srs/tools/backtrace/Makefile @@ -0,0 +1,24 @@ +.PHONY: default clean + +LDLIBS=../../obj/libst.a -ldl +CFLAGS=-g -O0 -rdynamic -I../../obj + +OS_NAME = $(shell uname -s) +ST_TARGET = linux-debug +ifeq ($(OS_NAME), Darwin) +ST_TARGET = darwin-debug +CPU_ARCHS = $(shell g++ -dM -E - +#include +#include + +#include + +#ifdef __linux__ +#include +#include +#include + +void* parse_symbol_offset(char* frame) +{ + char* p = NULL; + char* p_symbol = NULL; + int nn_symbol = 0; + char* p_offset = NULL; + int nn_offset = 0; + + // Read symbol and offset, for example: + // /tools/backtrace(foo+0x1820) [0x555555555820] + for (p = frame; *p; p++) { + if (*p == '(') { + p_symbol = p + 1; + } else if (*p == '+') { + if (p_symbol) nn_symbol = p - p_symbol; + p_offset = p + 1; + } else if (*p == ')') { + if (p_offset) nn_offset = p - p_offset; + } + } + if (!nn_symbol && !nn_offset) { + return NULL; + } + + // Convert offset(0x1820) to pointer, such as 0x1820. + char tmp[128]; + if (!nn_offset || nn_offset >= sizeof(tmp)) { + return NULL; + } + + int r0 = EOF; + void* offset = NULL; + tmp[nn_offset] = 0; + if ((r0 = sscanf(strncpy(tmp, p_offset, nn_offset), "%p", &offset)) == EOF) { + return NULL; + } + + // Covert symbol(foo) to offset, such as 0x2fba. + if (!nn_symbol || nn_symbol >= sizeof(tmp)) { + return offset; + } + + void* object_file; + if ((object_file = dlopen(NULL, RTLD_LAZY)) == NULL) { + return offset; + } + + void* address; + tmp[nn_symbol] = 0; + if ((address = dlsym(object_file, strncpy(tmp, p_symbol, nn_symbol))) == NULL) { + dlclose(object_file); + return offset; + } + + Dl_info symbol_info; + if ((r0 = dladdr(address, &symbol_info)) == 0) { + dlclose(object_file); + return offset; + } + + dlclose(object_file); + return symbol_info.dli_saddr - symbol_info.dli_fbase + offset; +} + +char* addr2line_format(void* addr, char* symbol, char* buffer, int nn_buffer) +{ + char cmd[512] = {0}; + int r0 = snprintf(cmd, sizeof(cmd), "addr2line -C -p -s -f -a -e %s %p", "backtrace", addr - 1); + if (r0 < 0 || r0 >= sizeof(cmd)) return symbol; + + FILE* fp = popen(cmd, "r"); + if (!fp) return symbol; + + char* p = fgets(buffer, nn_buffer, fp); + pclose(fp); + + if (p == NULL) return symbol; + if ((r0 = strlen(p)) == 0) return symbol; + + // Trait the last newline if exists. + if (p[r0 - 1] == '\n') p[r0 - 1] = '\0'; + + // Find symbol not match by addr2line, like + // 0x0000000000021c87: ?? ??:0 + // 0x0000000000002ffa: _start at ??:? + for (p = buffer; p < buffer + r0 - 1; p++) { + if (p[0] == '?' && p[1] == '?') return symbol; + } + + return buffer; +} +#endif + +#ifdef __linux__ +void bar2() +{ + void* addresses[64]; + int nn_addresses = backtrace(addresses, sizeof(addresses) / sizeof(void*)); + printf("\naddresses:\n"); + for (int i = 0; i < nn_addresses; i++) { + printf("%p\n", addresses[i]); + } + + char** symbols = backtrace_symbols(addresses, nn_addresses); + printf("\nsymbols:\n"); + for (int i = 0; i < nn_addresses; i++) { + printf("%s\n", symbols[i]); + } + + char buffer[128]; + printf("\nframes:\n"); + for (int i = 0; i < nn_addresses; i++) { + void* frame = parse_symbol_offset(symbols[i]); + char* fmt = addr2line_format(frame, symbols[i], buffer, sizeof(buffer)); + int parsed = (fmt == buffer); + printf("%p %d %s\n", frame, parsed, fmt); + } + + free(symbols); + + printf("bar2 OK\n"); + return; +} +#endif + +int always_use_builtin = 0; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-address" +void bar() { + // Each item in the array pointed to by buffer is of type void *, and is the return address from the corresponding + // stack frame. + void* addresses[64]; + int nn_addresses = backtrace(addresses, sizeof(addresses) / sizeof(void*)); + + if (!nn_addresses || always_use_builtin) { + printf("Try to get return addresses by __builtin_return_address\n"); + void* p = NULL; nn_addresses = 0; + if ((p = __builtin_return_address(0)) != NULL) { + addresses[nn_addresses++] = p; + if ((p = __builtin_return_address(1)) != NULL) { + addresses[nn_addresses++] = p; + if ((p = __builtin_return_address(2)) != NULL) { + addresses[nn_addresses++] = p; + if ((p = __builtin_return_address(3)) != NULL) { + addresses[nn_addresses++] = p; + if ((p = __builtin_return_address(4)) != NULL) { + addresses[nn_addresses++] = p; + if ((p = __builtin_return_address(5)) != NULL) { + addresses[nn_addresses++] = p; + } + } + } + } + } + } + } + + char** symbols = backtrace_symbols(addresses, nn_addresses); + printf("nn_addresses=%d, symbols=%p, symbols[0]=%p\n", nn_addresses, symbols, symbols[0]); + + printf("\naddresses:\n"); + for (int i = 0; i < nn_addresses; i++) { + printf("%p\n", addresses[i]); + } + + printf("\nsymbols:\n"); + for (int i = 0; i < nn_addresses; i++) { + printf("%s\n", symbols[i]); + } + free(symbols); + + printf("bar OK\n"); + return; +} +#pragma GCC diagnostic pop + +void foo() { + bar(); +#ifdef __linux__ + bar2(); +#endif + + printf("foo OK\n"); + return; +} + +void* start(void* arg) +{ + foo(); + + printf("coroutine OK\n"); + return NULL; +} + +int main(int argc, char** argv) +{ + if (argc > 1) { + always_use_builtin = 1; + } + + st_init(); + + st_thread_create(start, NULL, 0, 0); + st_thread_exit(NULL); + + printf("main done\n"); + return 0; +} + diff --git a/trunk/3rdparty/st-srs/tools/helloworld/Makefile b/trunk/3rdparty/st-srs/tools/helloworld/Makefile index 24e185042..7ec0d2aa6 100644 --- a/trunk/3rdparty/st-srs/tools/helloworld/Makefile +++ b/trunk/3rdparty/st-srs/tools/helloworld/Makefile @@ -13,7 +13,7 @@ CFLAGS += -arch $(CPU_ARCHS) endif ./helloworld: helloworld.c $(LDLIBS) - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o helloworld helloworld.c $(LDLIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) clean: cd ../.. && make clean diff --git a/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c b/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c index 0ce1de5de..778704445 100644 --- a/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c +++ b/trunk/3rdparty/st-srs/tools/helloworld/helloworld.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2021 Winlin */ +/* Copyright (c) 2013-2022 Winlin */ #include diff --git a/trunk/3rdparty/st-srs/tools/jmpbuf/.gitignore b/trunk/3rdparty/st-srs/tools/jmpbuf/.gitignore index 2d81d8fc5..c3a424aad 100644 --- a/trunk/3rdparty/st-srs/tools/jmpbuf/.gitignore +++ b/trunk/3rdparty/st-srs/tools/jmpbuf/.gitignore @@ -1,3 +1,3 @@ jmpbuf -jmpbuf.E.c +jmpbuf.E.txt diff --git a/trunk/3rdparty/st-srs/tools/jmpbuf/Makefile b/trunk/3rdparty/st-srs/tools/jmpbuf/Makefile index 11271b0b6..e399c3ea5 100644 --- a/trunk/3rdparty/st-srs/tools/jmpbuf/Makefile +++ b/trunk/3rdparty/st-srs/tools/jmpbuf/Makefile @@ -12,14 +12,14 @@ CPU_ARCHS += $(shell g++ -dM -E - #include +#include +#include -int foo_return_zero(); -int foo_return_one(); -int foo_return_one_arg1(int r0); -extern void print_buf(unsigned char* p, int nn_jb); -extern void print_jmpbuf(); +void bar() +{ +} + +void foo() +{ + bar(); +} int main(int argc, char** argv) { @@ -19,6 +24,12 @@ int main(int argc, char** argv) #ifdef __APPLE__ printf("__APPLE__: %d\n", __APPLE__); #endif +#ifdef __CYGWIN__ + printf("__CYGWIN__: %d\n", __CYGWIN__); +#endif +#ifdef _WIN32 + printf("_WIN32: %d\n", _WIN32); +#endif printf("\nCPU specs:\n"); #ifdef __mips__ @@ -48,219 +59,21 @@ int main(int argc, char** argv) #ifdef __GLIBC__ printf("__GLIBC__: %d\n", __GLIBC__); #endif - printf("sizeof(long)=%d\n", (int)sizeof(long)); - printf("sizeof(long long int)=%d\n", (int)sizeof(long long int)); - printf("sizeof(void*)=%d\n", (int)sizeof(void*)); -#ifdef __ptr_t - printf("sizeof(__ptr_t)=%d\n", (int)sizeof(__ptr_t)); -#endif - - printf("\nReturn value:\n"); - int r0 = foo_return_zero(); - int r1 = foo_return_one(); - int r2 = foo_return_one_arg1(r1); - printf("foo_return_zero=%d, foo_return_one=%d, foo_return_one_arg1=%d\n", r0, r1, r2); printf("\nCalling conventions:\n"); - print_jmpbuf(); + foo(); + printf("\nCall setjmp:\n"); + jmp_buf ctx; + if (!setjmp(ctx)) { + printf("Call longjmp with return=1\n"); + longjmp(ctx, 1); + + // Not reachable code. + printf("Should never be here.\n"); + } + + printf("\nDone\n"); return 0; } -int foo_return_zero() -{ - return 0; -} - -int foo_return_one() -{ - return 1; -} - -int foo_return_one_arg1(int r0) -{ - return r0 + 2; -} - -#ifdef __linux__ - -#if defined(__riscv) || defined(__arm__) || defined(__aarch64__) -void print_jmpbuf() { -} -#elif __mips64 -void print_jmpbuf() -{ - // https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions - register void* ra asm("ra"); - register void* gp asm("gp"); - register void* sp asm("sp"); - register void* fp asm("fp"); - // $s0–$s7 $16–$23 saved temporaries - register void* s0 asm("s0"); - register void* s1 asm("s1"); - register void* s2 asm("s2"); - register void* s3 asm("s3"); - register void* s4 asm("s4"); - register void* s5 asm("s5"); - register void* s6 asm("s6"); - register void* s7 asm("s7"); - - /* - typedef unsigned long long __jmp_buf[13]; - typedef struct __jmp_buf_tag { - __jmp_buf __jmpbuf; - int __mask_was_saved; - __sigset_t __saved_mask; - } jmp_buf[1]; - */ - jmp_buf ctx = {0}; - int r0 = setjmp(ctx); - if (!r0) { - longjmp(ctx, 1); - } - - printf("ra=%p, sp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p, gp=%p\n", - ra, sp, s0, s1, s2, s3, s4, s5, s6, s7, fp, gp); - - int nn_jb = sizeof(ctx[0].__jmpbuf); - printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); - - unsigned char* p = (unsigned char*)ctx[0].__jmpbuf; - print_buf(p, nn_jb); -} -#elif __mips__ -void print_jmpbuf() -{ - // https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions - register void* ra asm("ra"); - register void* gp asm("gp"); - register void* sp asm("sp"); - register void* fp asm("fp"); - // $s0–$s7 $16–$23 saved temporaries - register void* s0 asm("s0"); - register void* s1 asm("s1"); - register void* s2 asm("s2"); - register void* s3 asm("s3"); - register void* s4 asm("s4"); - register void* s5 asm("s5"); - register void* s6 asm("s6"); - register void* s7 asm("s7"); - - /* - typedef unsigned long long __jmp_buf[13]; - typedef struct __jmp_buf_tag { - __jmp_buf __jb; - unsigned long __fl; - unsigned long __ss[128/sizeof(long)]; - } jmp_buf[1]; - */ - jmp_buf ctx = {0}; - int r0 = setjmp(ctx); - if (!r0) { - longjmp(ctx, 1); - } - - printf("ra=%p, sp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p, gp=%p\n", - ra, sp, s0, s1, s2, s3, s4, s5, s6, s7, fp, gp); - - int nn_jb = sizeof(ctx[0].__jb); - printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); - - unsigned char* p = (unsigned char*)ctx[0].__jb; - print_buf(p, nn_jb); -} -#elif __loongarch64 -void print_jmpbuf() -{ - // https://github.com/ossrs/state-threads/issues/24#porting - register void* ra asm("r1"); // r1, ra, Return address - register void* sp asm("r3"); // r3, sp, Stack pointer - register void* fp asm("r22"); // r22, fp, Frame pointer - // r23-r31, s0-s8, Subroutine register variable - register void* s0 asm("r23"); - register void* s1 asm("r24"); - register void* s2 asm("r25"); - register void* s3 asm("r26"); - register void* s4 asm("r27"); - register void* s5 asm("r28"); - register void* s6 asm("r29"); - register void* s7 asm("r30"); - register void* s8 asm("r31"); - - /* - struct __jmp_buf_tag { - __jmp_buf __jmpbuf; - int __mask_was_saved; - __sigset_t __saved_mask; - }; - typedef struct __jmp_buf_tag jmp_buf[1]; - */ - jmp_buf ctx = {0}; - int r0 = setjmp(ctx); - if (!r0) { - longjmp(ctx, 1); - } - - printf("ra=%p, sp=%p, fp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, s7=%p\n", - ra, sp, fp, s0, s1, s2, s3, s4, s5, s6, s7, s8); - - int nn_jb = sizeof(ctx[0].__jmpbuf); - printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); - - unsigned char* p = (unsigned char*)ctx[0].__jmpbuf; - print_buf(p, nn_jb); -} -#endif -#endif - -#ifdef __APPLE__ -#ifdef __x86_64__ -void print_jmpbuf() -{ - // https://courses.cs.washington.edu/courses/cse378/10au/sections/Section1_recap.pdf - void *rbx, *rbp, *r12, *r13, *r14, *r15, *rsp; - __asm__ __volatile__ ("movq %%rbx,%0": "=r"(rbx): /* No input */); - __asm__ __volatile__ ("movq %%rbp,%0": "=r"(rbp): /* No input */); - __asm__ __volatile__ ("movq %%r12,%0": "=r"(r12): /* No input */); - __asm__ __volatile__ ("movq %%r13,%0": "=r"(r13): /* No input */); - __asm__ __volatile__ ("movq %%r14,%0": "=r"(r14): /* No input */); - __asm__ __volatile__ ("movq %%r15,%0": "=r"(r15): /* No input */); - __asm__ __volatile__ ("movq %%rsp,%0": "=r"(rsp): /* No input */); - - printf("rbx=%p, rbp=%p, r12=%p, r13=%p, r14=%p, r15=%p, rsp=%p\n", - rbx, rbp, r12, r13, r14, r15, rsp); - - jmp_buf ctx = {0}; - int r0 = setjmp(ctx); - if (!r0) { - longjmp(ctx, 1); - } - - int nn_jb = sizeof(ctx); - printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); - - unsigned char* p = (unsigned char*)ctx; - print_buf(p, nn_jb); -} -#endif -#endif - -void print_buf(unsigned char* p, int nn_jb) -{ - printf(" "); - - int i; - for (i = 0; i < nn_jb; i++) { - printf("0x%02x ", (unsigned char)p[i]); - - int newline = ((i + 1) % sizeof(void*)); - if (!newline || i == nn_jb - 1) { - printf("\n"); - } - - if (!newline && i < nn_jb - 1) { - printf(" "); - } - } -} - diff --git a/trunk/3rdparty/st-srs/tools/verify/Makefile b/trunk/3rdparty/st-srs/tools/verify/Makefile index 8e55bd67a..3801f3bf2 100644 --- a/trunk/3rdparty/st-srs/tools/verify/Makefile +++ b/trunk/3rdparty/st-srs/tools/verify/Makefile @@ -1,7 +1,7 @@ .PHONY: clean LDLIBS=../../obj/libst.a -CFLAGS=-g -O0 +CFLAGS=-g -O0 -I../../obj OS_NAME = $(shell uname -s) ST_TARGET = linux-debug @@ -13,7 +13,7 @@ CFLAGS += -arch $(CPU_ARCHS) endif ./verify: verify.c $(LDLIBS) - $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o verify verify.c $(LDLIBS) + $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) clean: cd ../.. && make clean diff --git a/trunk/3rdparty/st-srs/tools/verify/verify.c b/trunk/3rdparty/st-srs/tools/verify/verify.c index ff91b966a..e59bc3173 100644 --- a/trunk/3rdparty/st-srs/tools/verify/verify.c +++ b/trunk/3rdparty/st-srs/tools/verify/verify.c @@ -1,134 +1,64 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2021 Winlin */ +/* Copyright (c) 2013-2022 Winlin */ #include -#include -extern int _st_md_cxt_save(jmp_buf env); -extern void _st_md_cxt_restore(jmp_buf env, int val); +#include +#include -void verify_jmpbuf(); -void print_buf(unsigned char* p, int nn_jb); +st_mutex_t lock; +st_cond_t cond; + +void* start(void* arg) +{ + printf("ST: thread run\n"); + + printf("ST: thread wait for a while\n"); + st_usleep(1.5 * 1000 * 1000); + printf("ST: thread wait done\n"); + + int r0 = st_cond_signal(cond); + printf("ST: thread cond signal, r0=%d\n", r0); + + printf("ST: thread lock\n"); + r0 = st_mutex_lock(lock); + assert(r0 == 0); + + r0 = st_mutex_unlock(lock); + printf("ST: thread unlock\n"); + + return NULL; +} int main(int argc, char** argv) { - verify_jmpbuf(); + int r0 = st_init(); + assert(r0 == 0); + printf("ST: main init ok\n"); + + lock = st_mutex_new(); + cond = st_cond_new(); + + st_thread_t trd = st_thread_create(start, NULL, 1, 0); + printf("ST: main create ok\n"); + + printf("ST: main lock\n"); + r0 = st_mutex_lock(lock); + assert(r0 == 0); + + printf("ST: main cond waiting\n"); + r0 = st_cond_wait(cond); + printf("ST: main cond wait ok, r0=%d\n", r0); + + r0 = st_mutex_unlock(lock); + printf("ST: main unlock\n"); + + st_thread_join(trd, NULL); + printf("ST: main done\n"); + + st_mutex_destroy(lock); + st_cond_destroy(cond); + return 0; } -#ifdef __linux__ -#ifdef __mips__ -void verify_jmpbuf() -{ - // https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions - register void* ra asm("ra"); - register void* gp asm("gp"); - register void* sp asm("sp"); - register void* fp asm("fp"); - // $s0–$s7 $16–$23 saved temporaries - register void* s0 asm("s0"); - register void* s1 asm("s1"); - register void* s2 asm("s2"); - register void* s3 asm("s3"); - register void* s4 asm("s4"); - register void* s5 asm("s5"); - register void* s6 asm("s6"); - register void* s7 asm("s7"); - - jmp_buf ctx = {0}; - int r0 = _st_md_cxt_save(ctx); - if (!r0) { - _st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1. - } - - printf("sp=%p, ra=%p, gp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p\n", - sp, ra, gp, s0, s1, s2, s3, s4, s5, s6, s7, fp); - - int nn_jb = sizeof(ctx[0].__jb); - unsigned char* p = (unsigned char*)ctx[0].__jb; - print_buf(p, nn_jb); -} -#elif __loongarch64 -void verify_jmpbuf() -{ - // https://github.com/ossrs/state-threads/issues/24#porting - register void* ra asm("r1"); // r1, ra, Return address - register void* sp asm("r3"); // r3, sp, Stack pointer - register void* fp asm("r22"); // r22, fp, Frame pointer - // r23-r31, s0-s8, Subroutine register variable - register void* s0 asm("r23"); - register void* s1 asm("r24"); - register void* s2 asm("r25"); - register void* s3 asm("r26"); - register void* s4 asm("r27"); - register void* s5 asm("r28"); - register void* s6 asm("r29"); - register void* s7 asm("r30"); - register void* s8 asm("r31"); - - jmp_buf ctx = {0}; - int r0 = _st_md_cxt_save(ctx); - if (!r0) { - _st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1. - } - - printf("sp=%p, ra=%p, fp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, s7=%p\n", - sp, ra, fp, s0, s1, s2, s3, s4, s5, s6, s7, s8); - - int nn_jb = sizeof(ctx[0].__jmpbuf); - unsigned char* p = (unsigned char*)ctx[0].__jmpbuf; - print_buf(p, nn_jb); -} -#endif -#endif - -#ifdef __APPLE__ -#ifdef __x86_64__ -void verify_jmpbuf() -{ - // https://courses.cs.washington.edu/courses/cse378/10au/sections/Section1_recap.pdf - void *rbx, *rbp, *r12, *r13, *r14, *r15, *rsp; - __asm__ __volatile__ ("movq %%rbx,%0": "=r"(rbx): /* No input */); - __asm__ __volatile__ ("movq %%rbp,%0": "=r"(rbp): /* No input */); - __asm__ __volatile__ ("movq %%r12,%0": "=r"(r12): /* No input */); - __asm__ __volatile__ ("movq %%r13,%0": "=r"(r13): /* No input */); - __asm__ __volatile__ ("movq %%r14,%0": "=r"(r14): /* No input */); - __asm__ __volatile__ ("movq %%r15,%0": "=r"(r15): /* No input */); - __asm__ __volatile__ ("movq %%rsp,%0": "=r"(rsp): /* No input */); - - printf("rbx=%p, rbp=%p, r12=%p, r13=%p, r14=%p, r15=%p, rsp=%p\n", - rbx, rbp, r12, r13, r14, r15, rsp); - - jmp_buf ctx = {0}; - int r0 = _st_md_cxt_save(ctx); - if (!r0) { - _st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1. - } - - int nn_jb = sizeof(ctx); - printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8); - - unsigned char* p = (unsigned char*)ctx; - print_buf(p, nn_jb); -} -#endif -#endif - -void print_buf(unsigned char* p, int nn_jb) -{ - printf(" "); - - for (int i = 0; i < nn_jb; i++) { - printf("0x%02x ", (unsigned char)p[i]); - - int newline = ((i + 1) % sizeof(void*)); - if (!newline || i == nn_jb - 1) { - printf("\n"); - } - - if (!newline && i < nn_jb - 1) { - printf(" "); - } - } -} - diff --git a/trunk/3rdparty/st-srs/utest/st_utest.cpp b/trunk/3rdparty/st-srs/utest/st_utest.cpp index f679a5dd6..568897fcc 100644 --- a/trunk/3rdparty/st-srs/utest/st_utest.cpp +++ b/trunk/3rdparty/st-srs/utest/st_utest.cpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2021 Winlin */ +/* Copyright (c) 2013-2022 Winlin */ #include diff --git a/trunk/3rdparty/st-srs/utest/st_utest.hpp b/trunk/3rdparty/st-srs/utest/st_utest.hpp index b4825a29d..e260cd0b6 100644 --- a/trunk/3rdparty/st-srs/utest/st_utest.hpp +++ b/trunk/3rdparty/st-srs/utest/st_utest.hpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2021 Winlin */ +/* Copyright (c) 2013-2022 Winlin */ #ifndef ST_UTEST_PUBLIC_HPP #define ST_UTEST_PUBLIC_HPP diff --git a/trunk/3rdparty/st-srs/utest/st_utest_coroutines.cpp b/trunk/3rdparty/st-srs/utest/st_utest_coroutines.cpp index 1ac022afb..03570df56 100644 --- a/trunk/3rdparty/st-srs/utest/st_utest_coroutines.cpp +++ b/trunk/3rdparty/st-srs/utest/st_utest_coroutines.cpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2021 Winlin */ +/* Copyright (c) 2013-2022 Winlin */ #include diff --git a/trunk/3rdparty/st-srs/utest/st_utest_tcp.cpp b/trunk/3rdparty/st-srs/utest/st_utest_tcp.cpp index 87168fe1a..fce8cb9fa 100644 --- a/trunk/3rdparty/st-srs/utest/st_utest_tcp.cpp +++ b/trunk/3rdparty/st-srs/utest/st_utest_tcp.cpp @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: MIT */ -/* Copyright (c) 2021 Winlin */ +/* Copyright (c) 2013-2022 Winlin */ #include diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index b03f5d224..eb069c5ae 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2022-10-21, ST: Refine tools and CMakeLists.txt. Add backtrace example. v5.0.79 * v5.0, 2022-10-10, For [#2901](https://github.com/ossrs/srs/issues/2901): Edge: Fast disconnect and reconnect. v5.0.78 * v5.0, 2022-10-09, Fix [#3198](https://github.com/ossrs/srs/issues/3198): SRT: Support PUSH SRT by IP and optional port. v5.0.76 * v5.0, 2022-10-06, GB28181: Support GB28181-2016 protocol. v5.0.74 diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index 870ded146..cd2aeaf39 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 78 +#define VERSION_REVISION 79 #endif