1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-13 03:41:55 +00:00

ST: Define and use a new jmpbuf. v5.0.57

This commit is contained in:
winlin 2022-09-01 11:51:04 +08:00
parent 7d47017a00
commit eb2056db25
8 changed files with 104 additions and 162 deletions

View file

@ -91,7 +91,7 @@ make cygwin64-debug
## Branch SRS ## Branch SRS
The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patched the following patches: The branch [srs](https://github.com/ossrs/state-threads/tree/srs) was patched and refined:
- [x] ARM: Patch [st.arm.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/1.st.arm.patch), for ARM. - [x] ARM: Patch [st.arm.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/1.st.arm.patch), for ARM.
- [x] OSX: Patch [st.osx.kqueue.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/3.st.osx.kqueue.patch), for osx. - [x] OSX: Patch [st.osx.kqueue.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/3.st.osx.kqueue.patch), for osx.
@ -114,7 +114,8 @@ The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patche
- [x] RISCV: Support RISCV for RISCV CPU, [#24](https://github.com/ossrs/state-threads/pull/28). - [x] RISCV: Support RISCV for RISCV CPU, [#24](https://github.com/ossrs/state-threads/pull/28).
- [x] MIPS: Support Linux/MIPS64 for loongson 3A4000/3B3000, [#21](https://github.com/ossrs/state-threads/pull/21). - [x] MIPS: Support Linux/MIPS64 for loongson 3A4000/3B3000, [#21](https://github.com/ossrs/state-threads/pull/21).
- [x] AppleM1: Support Apple Silicon M1(aarch64), [#30](https://github.com/ossrs/state-threads/issues/30). - [x] AppleM1: Support Apple Silicon M1(aarch64), [#30](https://github.com/ossrs/state-threads/issues/30).
- [ ] IDE: Support CLion for debugging and learning. - [x] IDE: Support CLion for debugging and learning.
- [x] Define and use a new jmpbuf, because the structure is different.
- [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12). - [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12).
## GDB Tools ## GDB Tools

View file

@ -170,7 +170,6 @@ typedef struct _st_cond {
_st_clist_t wait_q; /* Condition variable wait queue */ _st_clist_t wait_q; /* Condition variable wait queue */
} _st_cond_t; } _st_cond_t;
typedef struct _st_thread _st_thread_t; typedef struct _st_thread _st_thread_t;
struct _st_thread { struct _st_thread {
@ -198,7 +197,7 @@ struct _st_thread {
_st_cond_t *term; /* Termination condition variable for join */ _st_cond_t *term; /* Termination condition variable for join */
jmp_buf context; /* Thread's context */ _st_jmp_buf_t context; /* Thread's context */
}; };

View file

@ -56,6 +56,35 @@
#define MAP_FAILED -1 #define MAP_FAILED -1
#endif #endif
/* We define the jmpbuf, because the system's is different in different OS */
typedef struct _st_jmp_buf {
/*
* OS CPU SIZE
* Darwin __amd64__/__x86_64__ long[8]
* Darwin __aarch64__ long[22]
* Linux __i386__ long[6]
* Linux __amd64__/__x86_64__ long[8]
* Linux __aarch64__ long[22]
* Linux __arm__ long[16]
* Linux __mips__/__mips64 long[13]
* Linux __riscv long[14]
* Linux __loongarch64 long[12]
* Cygwin64 __amd64__/__x86_64__ long[8]
*/
long __jmpbuf[22];
} _st_jmp_buf_t[1];
extern int _st_md_cxt_save(_st_jmp_buf_t env);
extern void _st_md_cxt_restore(_st_jmp_buf_t env, int val);
/* Always use builtin setjmp/longjmp, use asm code. */
#define MD_USE_BUILTIN_SETJMP
#define MD_SETJMP(env) _st_md_cxt_save(env)
#define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
#if defined(USE_LIBC_SETJMP)
#error The libc setjmp is not supported now
#endif
/***************************************** /*****************************************
* Platform specifics * Platform specifics
*/ */
@ -66,14 +95,10 @@
#define MD_ACCEPT_NB_INHERITED #define MD_ACCEPT_NB_INHERITED
#define MD_HAVE_SOCKLEN_T #define MD_HAVE_SOCKLEN_T
#define MD_USE_BUILTIN_SETJMP
#if defined(__amd64__) || defined(__x86_64__) #if defined(__amd64__) || defined(__x86_64__)
#define JB_SP 12 /* The jmpbuf is int(4B) array, while MD_GET_SP covert to long(8B) pointer, so the JB_SP should be 12 which is 6*sizeof(long)/sizeof(int) */ #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6]))
#define MD_GET_SP(_t) *((long *)&((_t)->context[JB_SP]))
#elif defined(__aarch64__) #elif defined(__aarch64__)
/* MUST be SP*2 because context is int array */ #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[13]))
#define MD_GET_SP(_t) *((long *)&((_t)->context[13 * 2]))
#else #else
#error Unknown CPU architecture #error Unknown CPU architecture
#endif #endif
@ -85,14 +110,6 @@
MD_GET_SP(_thread) = (long) (_sp); \ MD_GET_SP(_thread) = (long) (_sp); \
ST_END_MACRO ST_END_MACRO
#if defined(MD_USE_BUILTIN_SETJMP)
#define MD_SETJMP(env) _st_md_cxt_save(env)
#define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
extern int _st_md_cxt_save(jmp_buf env);
extern void _st_md_cxt_restore(jmp_buf env, int val);
#endif
#define MD_GET_UTIME() \ #define MD_GET_UTIME() \
struct timeval tv; \ struct timeval tv; \
(void) gettimeofday(&tv, NULL); \ (void) gettimeofday(&tv, NULL); \
@ -120,112 +137,38 @@
(void) gettimeofday(&tv, NULL); \ (void) gettimeofday(&tv, NULL); \
return (tv.tv_sec * 1000000LL + tv.tv_usec) return (tv.tv_sec * 1000000LL + tv.tv_usec)
#if 1 #if defined(__i386__)
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[4]))
/* #elif defined(__amd64__) || defined(__x86_64__)
* On linux, there are a few styles of jmpbuf format. These vary based #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6]))
* on architecture/glibc combination. #elif defined(__aarch64__)
* /* https://github.com/ossrs/state-threads/issues/9 */
* Most of the glibc based toggles were lifted from: #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[13]))
* mozilla/nsprpub/pr/include/md/_linux.h #elif defined(__arm__)
*/ /* https://github.com/ossrs/state-threads/issues/1#issuecomment-244648573 */
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[8]))
/* #elif defined(__mips64)
* Starting with glibc 2.4, JB_SP definitions are not public anymore. /* https://github.com/ossrs/state-threads/issues/21 */
* They, however, can still be found in glibc source tree in #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
* architecture-specific "jmpbuf-offsets.h" files. #elif defined(__mips__)
* Most importantly, the content of jmp_buf is mangled by setjmp to make /* https://github.com/ossrs/state-threads/issues/21 */
* it completely opaque (the mangling can be disabled by setting the #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
* LD_POINTER_GUARD environment variable before application execution). #elif defined(__riscv)
* Therefore we will use built-in _st_md_cxt_save/_st_md_cxt_restore /* https://github.com/ossrs/state-threads/pull/28 */
* functions as a setjmp/longjmp replacement wherever they are available #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
* unless USE_LIBC_SETJMP is defined. #elif defined(__loongarch64)
*/ /* https://github.com/ossrs/state-threads/issues/24 */
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
#if defined(__i386__)
#define MD_USE_BUILTIN_SETJMP
#if defined(__GLIBC__) && __GLIBC__ >= 2
#ifndef JB_SP
#define JB_SP 4
#endif
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
#else
/* not an error but certainly cause for caution */
#error "Untested use of old glibc on i386"
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
#endif
#elif defined(__amd64__) || defined(__x86_64__)
#define MD_USE_BUILTIN_SETJMP
#ifndef JB_RSP
#define JB_RSP 6
#endif
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_RSP]
#elif defined(__aarch64__)
/* https://github.com/ossrs/state-threads/issues/9 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[13]
#elif defined(__arm__)
/* https://github.com/ossrs/state-threads/issues/1#issuecomment-244648573 */
#define MD_USE_BUILTIN_SETJMP
/* force to use glibc solution, hack the guard jmpbuf from michaeltalyansky */
#ifdef USE_LIBC_SETJMP
#undef MD_USE_BUILTIN_SETJMP
#endif
#if defined(__GLIBC__) && __GLIBC__ >= 2
/* Merge from https://github.com/michaeltalyansky/state-threads/commit/56554a5c425aee8e7a73782eae23d74d83c4120a */
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[8]
#else
#error "ARM/Linux pre-glibc2 not supported yet"
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
#elif defined(__mips64)
/* https://github.com/ossrs/state-threads/issues/21 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
#elif defined(__mips__)
/* https://github.com/ossrs/state-threads/issues/21 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jb[0]))
#elif defined(__riscv)
/* https://github.com/ossrs/state-threads/pull/28 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
#elif defined(__loongarch64)
/* https://github.com/ossrs/state-threads/issues/24 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
#else
#error "Unknown CPU architecture"
#endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
ST_BEGIN_MACRO \
if (MD_SETJMP((_thread)->context)) \
_main(); \
MD_GET_SP(_thread) = (long) (_sp); \
ST_END_MACRO
#endif /* Cases with different MD_INIT_CONTEXT */
#if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP)
#define MD_SETJMP(env) _st_md_cxt_save(env)
#define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
extern int _st_md_cxt_save(jmp_buf env);
extern void _st_md_cxt_restore(jmp_buf env, int val);
#else #else
#define MD_SETJMP(env) setjmp(env) #error "Unknown CPU architecture"
#define MD_LONGJMP(env, val) longjmp(env, val) #endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
#endif
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
ST_BEGIN_MACRO \
if (MD_SETJMP((_thread)->context)) \
_main(); \
MD_GET_SP(_thread) = (long) (_sp); \
ST_END_MACRO
#elif defined (CYGWIN64) #elif defined (CYGWIN64)
@ -237,8 +180,7 @@
#define MD_USE_BUILTIN_SETJMP #define MD_USE_BUILTIN_SETJMP
#if defined(__amd64__) || defined(__x86_64__) #if defined(__amd64__) || defined(__x86_64__)
#define JB_SP 6 // The context is long(32) array, @see https://github.com/ossrs/state-threads/issues/20#issuecomment-887569093 #define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[6]))
#define MD_GET_SP(_t) *((long *)&((_t)->context[JB_SP]))
#else #else
#error Unknown CPU architecture #error Unknown CPU architecture
#endif #endif
@ -250,14 +192,6 @@
MD_GET_SP(_thread) = (long) (_sp); \ MD_GET_SP(_thread) = (long) (_sp); \
ST_END_MACRO ST_END_MACRO
#if defined(MD_USE_BUILTIN_SETJMP)
#define MD_SETJMP(env) _st_md_cxt_save(env)
#define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
extern int _st_md_cxt_save(jmp_buf env);
extern void _st_md_cxt_restore(jmp_buf env, int val);
#endif
#define MD_GET_UTIME() \ #define MD_GET_UTIME() \
struct timeval tv; \ struct timeval tv; \
(void) gettimeofday(&tv, NULL); \ (void) gettimeofday(&tv, NULL); \

View file

@ -618,15 +618,6 @@ void st_thread_interrupt(_st_thread_t *thread)
} }
/* Merge from https://github.com/michaeltalyansky/state-threads/commit/cce736426c2320ffec7c9820df49ee7a18ae638c */
#if defined(__arm__) && !defined(MD_USE_BUILTIN_SETJMP) && __GLIBC_MINOR__ >= 19
extern unsigned long __pointer_chk_guard;
#define PTR_MANGLE(var) \
(var) = (__typeof (var)) ((unsigned long) (var) ^ __pointer_chk_guard)
#define PTR_DEMANGLE(var) PTR_MANGLE (var)
#endif
_st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stk_size) _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stk_size)
{ {
_st_thread_t *thread; _st_thread_t *thread;
@ -662,17 +653,9 @@ _st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinabl
thread->stack = stack; thread->stack = stack;
thread->start = start; thread->start = start;
thread->arg = arg; thread->arg = arg;
/* Merge from https://github.com/michaeltalyansky/state-threads/commit/cce736426c2320ffec7c9820df49ee7a18ae638c */ _ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);
#if defined(__arm__) && !defined(MD_USE_BUILTIN_SETJMP) && __GLIBC_MINOR__ >= 19
volatile void * lsp = PTR_MANGLE(stack->sp);
if (_setjmp ((thread)->context))
_st_thread_main();
(thread)->context[0].__jmpbuf[8] = (long) (lsp);
#else
_ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);
#endif
/* If thread is joinable, allocate a termination condition variable */ /* If thread is joinable, allocate a termination condition variable */
if (joinable) { if (joinable) {
thread->term = st_cond_new(); thread->term = st_cond_new();
@ -720,19 +703,19 @@ int _st_iterate_threads_flag = 0;
void _st_iterate_threads(void) void _st_iterate_threads(void)
{ {
static __thread _st_thread_t *thread = NULL; static __thread _st_thread_t *thread = NULL;
static __thread jmp_buf orig_jb, save_jb; static __thread _st_jmp_buf_t orig_jb, save_jb;
_st_clist_t *q; _st_clist_t *q;
if (!_st_iterate_threads_flag) { if (!_st_iterate_threads_flag) {
if (thread) { if (thread) {
memcpy(thread->context, save_jb, sizeof(jmp_buf)); memcpy(thread->context, save_jb, sizeof(_st_jmp_buf_t));
MD_LONGJMP(orig_jb, 1); MD_LONGJMP(orig_jb, 1);
} }
return; return;
} }
if (thread) { if (thread) {
memcpy(thread->context, save_jb, sizeof(jmp_buf)); memcpy(thread->context, save_jb, sizeof(_st_jmp_buf_t));
_st_show_thread_stack(thread, NULL); _st_show_thread_stack(thread, NULL);
} else { } else {
if (MD_SETJMP(orig_jb)) { if (MD_SETJMP(orig_jb)) {
@ -752,7 +735,7 @@ void _st_iterate_threads(void)
thread = _ST_THREAD_THREADQ_PTR(q); thread = _ST_THREAD_THREADQ_PTR(q);
if (thread == _ST_CURRENT_THREAD()) if (thread == _ST_CURRENT_THREAD())
MD_LONGJMP(orig_jb, 1); MD_LONGJMP(orig_jb, 1);
memcpy(save_jb, thread->context, sizeof(jmp_buf)); memcpy(save_jb, thread->context, sizeof(_st_jmp_buf_t));
MD_LONGJMP(thread->context, 1); MD_LONGJMP(thread->context, 1);
} }
#endif /* DEBUG */ #endif /* DEBUG */

View file

@ -1,5 +1,6 @@
.PHONY: default clean .PHONY: default clean
LDLIBS=
CFLAGS=-g -O0 CFLAGS=-g -O0
OS_NAME = $(shell uname -s) OS_NAME = $(shell uname -s)
@ -13,7 +14,7 @@ endif
default: ./jmpbuf ./jmpbuf.E.c default: ./jmpbuf ./jmpbuf.E.c
./jmpbuf: jmpbuf.c ./jmpbuf: jmpbuf.c $(LDLIBS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS) $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS)
./jmpbuf.E.c: jmpbuf.c ./jmpbuf.E.c: jmpbuf.c

View file

@ -4,13 +4,36 @@
#include <stdio.h> #include <stdio.h>
#include <setjmp.h> #include <setjmp.h>
/* We define the jmpbuf, because the system's is different in different OS */
typedef struct _st_jmp_buf {
/*
* OS CPU SIZE
* Darwin __amd64__/__x86_64__ long[8]
* Darwin __aarch64__ long[22]
* Linux __i386__ long[6]
* Linux __amd64__/__x86_64__ long[8]
* Linux __aarch64__ long[22]
* Linux __arm__ long[16]
* Linux __mips__/__mips64 long[13]
* Linux __riscv long[14]
* Linux __loongarch64 long[12]
* Cygwin64 __amd64__/__x86_64__ long[8]
*/
long __jmpbuf[22];
} _st_jmp_buf_t[1];
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
jmp_buf ctx = {0}; jmp_buf ctx = {0};
int r0 = setjmp(ctx); int r0 = setjmp(ctx);
int nn_jb = sizeof(ctx); int nn_jb = sizeof(ctx);
printf("r0=%d, sizeof(jmp_buf)=%d (unsigned long long [%d])\n", r0, nn_jb, nn_jb/8); printf("jmp_buf: r0=%d, sizeof(jmp_buf)=%d (unsigned long long [%d])\n", r0, nn_jb, nn_jb/8);
_st_jmp_buf_t ctx2 = {0};
int r1 = sizeof(_st_jmp_buf_t);
int r2 = sizeof(ctx2);
printf("_st_jmp_buf_t: sizeof(_st_jmp_buf_t)=%d/%d (unsigned long long [%d])\n", r1, r2, r2/8);
return 0; return 0;
} }

View file

@ -7,7 +7,8 @@ The changelog for SRS.
## SRS 5.0 Changelog ## SRS 5.0 Changelog
* v5.0, 2022-08-31, Fix URL parsing bug for `__defaultVhost__`. v5.0.55 * v5.0, 2022-09-01, ST: Define and use a new jmpbuf. v5.0.57
* v5.0, 2022-08-31, Fix URL parsing bug for `__defaultVhost__`. v5.0.56
* v5.0, 2022-08-30, Fix [#2837](https://github.com/ossrs/srs/issues/2837): Callback: Support stream_url and stream_id. v5.0.55 * v5.0, 2022-08-30, Fix [#2837](https://github.com/ossrs/srs/issues/2837): Callback: Support stream_url and stream_id. v5.0.55
* v5.0, 2022-08-30, STAT: Refine tcUrl for SRT/RTC. v5.0.54 * v5.0, 2022-08-30, STAT: Refine tcUrl for SRT/RTC. v5.0.54
* v5.0, 2022-08-30, Refactor: Extract SrsNetworkKbps from SrsKbps. v5.0.53 * v5.0, 2022-08-30, Refactor: Extract SrsNetworkKbps from SrsKbps. v5.0.53

View file

@ -9,6 +9,6 @@
#define VERSION_MAJOR 5 #define VERSION_MAJOR 5
#define VERSION_MINOR 0 #define VERSION_MINOR 0
#define VERSION_REVISION 56 #define VERSION_REVISION 57
#endif #endif