diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2023-10-04 21:12:59 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2023-10-04 21:12:59 (GMT) |
| commit | 8f1f56d42b418a9e91029a8c59be886facf7cb21 (patch) | |
| tree | e56c722c99076cf07c7240789f95436896d39eed /generic/tclBasic.c | |
| parent | cb6c9c4787b898a85c3b1577906d50d0ba793118 (diff) | |
| parent | 600c5b59541d100659c84992a2e118b7eba65e41 (diff) | |
| download | tcl-8f1f56d42b418a9e91029a8c59be886facf7cb21.zip tcl-8f1f56d42b418a9e91029a8c59be886facf7cb21.tar.gz tcl-8f1f56d42b418a9e91029a8c59be886facf7cb21.tar.bz2 | |
Merge 8.7
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 3ceb427..4f43ca5 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 @@ -9211,6 +9246,7 @@ TclNRCoroutineActivateCallback( TCL_UNUSED(int) /*result*/) { CoroutineData *corPtr = (CoroutineData *)data[0]; + void *stackLevel = TclGetCStackPtr(); if (!corPtr->stackLevel) { /* @@ -9227,7 +9263,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; @@ -9241,7 +9277,7 @@ TclNRCoroutineActivateCallback( * Coroutine is active: yield */ - if (corPtr->stackLevel != &corPtr) { + if (corPtr->stackLevel != stackLevel) { NRE_callback *runPtr; iPtr->execEnvPtr = corPtr->callerEEPtr; |
