diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2023-10-04 20:54:28 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2023-10-04 20:54:28 (GMT) |
| commit | 600c5b59541d100659c84992a2e118b7eba65e41 (patch) | |
| tree | 3559aad7f431a5adbdb7ed219044955faceaa83d /generic/tclBasic.c | |
| parent | 1081ce3d811ca2df171d764f1611eb89d8a891b3 (diff) | |
| parent | d6de3e27b418588da31a5a14d20a6bf03289c876 (diff) | |
| download | tcl-600c5b59541d100659c84992a2e118b7eba65e41.zip tcl-600c5b59541d100659c84992a2e118b7eba65e41.tar.gz tcl-600c5b59541d100659c84992a2e118b7eba65e41.tar.bz2 | |
Merge 8.6
Diffstat (limited to 'generic/tclBasic.c')
| -rw-r--r-- | generic/tclBasic.c | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 318374e..4187462 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -64,6 +64,41 @@ #endif /* !TCL_FPCLASSIFY_MODE */ +/* + * Bug 7371b6270b: to check C call stack depth, prefer an approach which is + * compatible with AddressSanitizer (ASan) use-after-return detection. + */ + +#if defined(HAVE_INTRIN_H) +#include <intrin.h> /* for _AddressOfReturnAddress() */ +#endif + +/* + * As suggested by + * https://clang.llvm.org/docs/LanguageExtensions.html#has-builtin + */ +#ifndef __has_builtin +#define __has_builtin(x) 0 /* for non-clang compilers */ +#endif + +void * +TclGetCStackPtr(void) +{ +#if defined(HAVE_INTRIN_H) + return _AddressOfReturnAddress(); +#elif __GNUC__ || __has_builtin(__builtin_frame_address) + return __builtin_frame_address(0); +#else + ptrdiff_t unused = 0; + /* + * LLVM recommends using volatile: + * https://github.com/llvm/llvm-project/blob/llvmorg-10.0.0-rc1/clang/lib/Basic/Stack.cpp#L31 + */ + ptrdiff_t *volatile stackLevel = &unused; + return (void *)stackLevel; +#endif +} + #define INTERP_STACK_INITIAL_SIZE 2000 #define CORO_STACK_INITIAL_SIZE 200 @@ -9726,6 +9761,7 @@ TclNRCoroutineActivateCallback( TCL_UNUSED(int) /*result*/) { CoroutineData *corPtr = (CoroutineData *)data[0]; + void *stackLevel = TclGetCStackPtr(); if (!corPtr->stackLevel) { /* @@ -9742,7 +9778,7 @@ TclNRCoroutineActivateCallback( * the interp's environment to make it suitable to run this coroutine. */ - corPtr->stackLevel = &corPtr; + corPtr->stackLevel = stackLevel; Tcl_Size numLevels = corPtr->auxNumLevels; corPtr->auxNumLevels = iPtr->numLevels; @@ -9756,7 +9792,7 @@ TclNRCoroutineActivateCallback( * Coroutine is active: yield */ - if (corPtr->stackLevel != &corPtr) { + if (corPtr->stackLevel != stackLevel) { NRE_callback *runPtr; iPtr->execEnvPtr = corPtr->callerEEPtr; |
