mirror of
https://github.com/ossrs/srs.git
synced 2025-02-13 03:41:55 +00:00
ST: Refine tools and CMakeLists.txt. Add backtrace example. v5.0.79
This commit is contained in:
parent
d9cf874033
commit
5a1a234855
18 changed files with 410 additions and 353 deletions
2
trunk/3rdparty/st-srs/README.md
vendored
2
trunk/3rdparty/st-srs/README.md
vendored
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
1
trunk/3rdparty/st-srs/tools/backtrace/.gitignore
vendored
Normal file
1
trunk/3rdparty/st-srs/tools/backtrace/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
backtrace
|
24
trunk/3rdparty/st-srs/tools/backtrace/Makefile
vendored
Normal file
24
trunk/3rdparty/st-srs/tools/backtrace/Makefile
vendored
Normal file
|
@ -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 - </dev/null |grep -q '__x86_64' && echo x86_64)
|
||||
CPU_ARCHS += $(shell g++ -dM -E - </dev/null |grep -q '__aarch64' && echo arm64)
|
||||
CFLAGS += -arch $(CPU_ARCHS)
|
||||
endif
|
||||
|
||||
./backtrace: backtrace.c $(LDLIBS)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS)
|
||||
|
||||
clean:
|
||||
cd ../.. && make clean
|
||||
rm -rf backtrace backtrace.dSYM
|
||||
|
||||
$(LDLIBS):
|
||||
cd ../.. && make $(ST_TARGET)
|
||||
|
228
trunk/3rdparty/st-srs/tools/backtrace/backtrace.c
vendored
Normal file
228
trunk/3rdparty/st-srs/tools/backtrace/backtrace.c
vendored
Normal file
|
@ -0,0 +1,228 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#ifdef __linux__
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <st.h>
|
||||
|
||||
#ifdef __linux__
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2021 Winlin */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
jmpbuf
|
||||
jmpbuf.E.c
|
||||
jmpbuf.E.txt
|
||||
|
||||
|
|
8
trunk/3rdparty/st-srs/tools/jmpbuf/Makefile
vendored
8
trunk/3rdparty/st-srs/tools/jmpbuf/Makefile
vendored
|
@ -12,14 +12,14 @@ CPU_ARCHS += $(shell g++ -dM -E - </dev/null |grep -q '__aarch64' && echo arm64
|
|||
CFLAGS += -arch $(CPU_ARCHS)
|
||||
endif
|
||||
|
||||
default: ./jmpbuf ./jmpbuf.E.c
|
||||
default: ./jmpbuf ./jmpbuf.E.txt
|
||||
|
||||
./jmpbuf: jmpbuf.c $(LDLIBS)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS)
|
||||
|
||||
./jmpbuf.E.c: jmpbuf.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -E -o jmpbuf.E.c $^ $(LDLIBS)
|
||||
./jmpbuf.E.txt: jmpbuf.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -E -o jmpbuf.E.txt $^ $(LDLIBS)
|
||||
|
||||
clean:
|
||||
rm -rf jmpbuf jmpbuf.E.c jmpbuf.dSYM
|
||||
rm -rf jmpbuf jmpbuf.E.txt jmpbuf.dSYM
|
||||
|
||||
|
|
245
trunk/3rdparty/st-srs/tools/porting/porting.c
vendored
245
trunk/3rdparty/st-srs/tools/porting/porting.c
vendored
|
@ -1,14 +1,19 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2021 Winlin */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <execinfo.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
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(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
trunk/3rdparty/st-srs/tools/verify/Makefile
vendored
4
trunk/3rdparty/st-srs/tools/verify/Makefile
vendored
|
@ -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
|
||||
|
|
176
trunk/3rdparty/st-srs/tools/verify/verify.c
vendored
176
trunk/3rdparty/st-srs/tools/verify/verify.c
vendored
|
@ -1,134 +1,64 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2021 Winlin */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <setjmp.h>
|
||||
extern int _st_md_cxt_save(jmp_buf env);
|
||||
extern void _st_md_cxt_restore(jmp_buf env, int val);
|
||||
#include <st.h>
|
||||
#include <assert.h>
|
||||
|
||||
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(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
trunk/3rdparty/st-srs/utest/st_utest.cpp
vendored
2
trunk/3rdparty/st-srs/utest/st_utest.cpp
vendored
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2021 Winlin */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#include <st_utest.hpp>
|
||||
|
||||
|
|
2
trunk/3rdparty/st-srs/utest/st_utest.hpp
vendored
2
trunk/3rdparty/st-srs/utest/st_utest.hpp
vendored
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2021 Winlin */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#include <st_utest.hpp>
|
||||
|
||||
|
|
2
trunk/3rdparty/st-srs/utest/st_utest_tcp.cpp
vendored
2
trunk/3rdparty/st-srs/utest/st_utest_tcp.cpp
vendored
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: MIT */
|
||||
/* Copyright (c) 2021 Winlin */
|
||||
/* Copyright (c) 2013-2022 Winlin */
|
||||
|
||||
#include <st_utest.hpp>
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
#define VERSION_MAJOR 5
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 78
|
||||
#define VERSION_REVISION 79
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue