forked from wolfSSL/wolfssl
wolfssl/test.h: polish implementation of HAVE_STACK_SIZE_VERBOSE, now enabled with --enable-stacksize-verbose; internal symbol renamed from original DEBUG_STACK_SIZE_VERBOSE, helper functions and macros refactored to be formally threadsafe and to track the overall high water mark (reports same "stack used" value as --enable-stacksize after final return); add "setting stack relative offset reference mark in funcname() to x" message at entry; add configure mutexing of --enable-stacksize[-verbose] relative to --enable-linuxkm.
This commit is contained in:
27
configure.ac
27
configure.ac
@@ -1918,6 +1918,18 @@ AC_ARG_ENABLE([stacksize],
|
||||
[ ENABLED_STACKSIZE=no ]
|
||||
)
|
||||
|
||||
# verbose, per-test stack size info, currently only implemented in testwolfcrypt
|
||||
AC_ARG_ENABLE([stacksize-verbose],
|
||||
[AS_HELP_STRING([--enable-stacksize-verbose],[Enable verbose stack size info on testwolfcrypt (default: disabled)])],
|
||||
[ ENABLED_STACKSIZE_VERBOSE=$enableval ],
|
||||
[ ENABLED_STACKSIZE_VERBOSE=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_STACKSIZE_VERBOSE" = "yes"
|
||||
then
|
||||
ENABLED_STACKSIZE=yes
|
||||
fi
|
||||
|
||||
if test "$ENABLED_STACKSIZE" = "yes"
|
||||
then
|
||||
AC_CHECK_FUNC([posix_memalign], [], [AC_MSG_ERROR(stacksize needs posix_memalign)])
|
||||
@@ -1925,6 +1937,15 @@ then
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_STACK_SIZE"
|
||||
fi
|
||||
|
||||
if test "$ENABLED_STACKSIZE_VERBOSE" = "yes"
|
||||
then
|
||||
if test "$thread_ls_on" != "yes"
|
||||
then
|
||||
AC_MSG_ERROR(stacksize-verbose needs thread-local storage.)
|
||||
fi
|
||||
AM_CFLAGS="$AM_CFLAGS -DHAVE_STACK_SIZE_VERBOSE"
|
||||
fi
|
||||
|
||||
|
||||
# MEMORY
|
||||
AC_ARG_ENABLE([memory],
|
||||
@@ -5377,6 +5398,12 @@ if test "x$ENABLED_LINUXKM" = "xyes"; then
|
||||
if test "$ENABLED_DEVCRYPTO" = "yes"; then
|
||||
AC_MSG_ERROR([--enable-devcrypto is incompatible with --enable-linuxkm.])
|
||||
fi
|
||||
if test "$ENABLED_STACKSIZE" = "yes"; then
|
||||
AC_MSG_ERROR([--enable-stacksize is incompatible with --enable-linuxkm.])
|
||||
fi
|
||||
if test "$ENABLED_STACKLOG" = "yes"; then
|
||||
AC_MSG_ERROR([--enable-stacklog is incompatible with --enable-linuxkm.])
|
||||
fi
|
||||
fi
|
||||
|
||||
# The following AM_CONDITIONAL statements set flags for use in the Makefiles.
|
||||
|
199
wolfssl/test.h
199
wolfssl/test.h
@@ -2002,107 +2002,49 @@ static WC_INLINE void CaCb(unsigned char* der, int sz, int type)
|
||||
typedef THREAD_RETURN WOLFSSL_THREAD (*thread_func)(void* args);
|
||||
#define STACK_CHECK_VAL 0x01
|
||||
|
||||
#ifdef DEBUG_STACK_SIZE_VERBOSE
|
||||
static unsigned char *StackSizeCheck_myStack = NULL;
|
||||
static size_t StackSizeCheck_stackSize = 0;
|
||||
static void *StackSizeCheck_stackOffsetPointer = 0;
|
||||
#endif
|
||||
#ifdef HAVE_STACK_SIZE_VERBOSE
|
||||
|
||||
static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
|
||||
{
|
||||
size_t i;
|
||||
int ret, used;
|
||||
void* status;
|
||||
unsigned char* myStack = NULL;
|
||||
size_t stackSize = 1024*176;
|
||||
pthread_attr_t myAttr;
|
||||
pthread_t threadId;
|
||||
/* per-subtest stack high water mark tracking.
|
||||
*
|
||||
* enable with
|
||||
*
|
||||
* CFLAGS='-g -DHAVE_STACK_SIZE_VERBOSE' ./configure --enable-stacksize [...]
|
||||
*/
|
||||
|
||||
#ifdef PTHREAD_STACK_MIN
|
||||
if (stackSize < PTHREAD_STACK_MIN)
|
||||
stackSize = PTHREAD_STACK_MIN;
|
||||
#endif
|
||||
static THREAD_LS_T unsigned char *StackSizeCheck_myStack = NULL;
|
||||
static THREAD_LS_T size_t StackSizeCheck_stackSize = 0;
|
||||
static THREAD_LS_T size_t StackSizeCheck_stackSizeHWM = 0;
|
||||
static THREAD_LS_T size_t *StackSizeCheck_stackSizeHWM_ptr = 0;
|
||||
static THREAD_LS_T void *StackSizeCheck_stackOffsetPointer = 0;
|
||||
|
||||
ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
|
||||
if (ret != 0 || myStack == NULL)
|
||||
err_sys_with_errno("posix_memalign failed\n");
|
||||
struct debug_stack_size_verbose_shim_args {
|
||||
unsigned char *myStack;
|
||||
size_t stackSize;
|
||||
size_t *stackSizeHWM_ptr;
|
||||
thread_func fn;
|
||||
void *args;
|
||||
};
|
||||
|
||||
XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
|
||||
|
||||
#ifdef DEBUG_STACK_SIZE_VERBOSE
|
||||
StackSizeCheck_myStack = myStack;
|
||||
StackSizeCheck_stackSize = stackSize;
|
||||
#endif
|
||||
|
||||
ret = pthread_attr_init(&myAttr);
|
||||
if (ret != 0)
|
||||
err_sys("attr_init failed");
|
||||
|
||||
ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
|
||||
if (ret != 0)
|
||||
err_sys("attr_setstackaddr failed");
|
||||
|
||||
ret = pthread_create(&threadId, &myAttr, tf, args);
|
||||
if (ret != 0) {
|
||||
perror("pthread_create failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = pthread_join(threadId, &status);
|
||||
if (ret != 0)
|
||||
err_sys("pthread_join failed");
|
||||
|
||||
for (i = 0; i < stackSize; i++) {
|
||||
if (myStack[i] != STACK_CHECK_VAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(myStack);
|
||||
#ifdef DEBUG_STACK_SIZE_VERBOSE
|
||||
StackSizeCheck_myStack = 0;
|
||||
return (int)((size_t)status);
|
||||
#endif
|
||||
|
||||
used = stackSize - i;
|
||||
printf("stack used = %d\n", used);
|
||||
|
||||
return (int)((size_t)status);
|
||||
static void *debug_stack_size_verbose_shim(struct debug_stack_size_verbose_shim_args *shim_args) {
|
||||
StackSizeCheck_myStack = shim_args->myStack;
|
||||
StackSizeCheck_stackSize = shim_args->stackSize;
|
||||
StackSizeCheck_stackSizeHWM_ptr = shim_args->stackSizeHWM_ptr;
|
||||
return shim_args->fn(shim_args->args);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_STACK_SIZE_VERBOSE
|
||||
|
||||
static WC_INLINE int StackSizeSetOffset(void *p)
|
||||
static WC_INLINE int StackSizeSetOffset(const char *funcname, void *p)
|
||||
{
|
||||
if (StackSizeCheck_myStack == NULL)
|
||||
return -BAD_FUNC_ARG;
|
||||
|
||||
StackSizeCheck_stackOffsetPointer = p;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WC_INLINE int StackSizeHWM(void)
|
||||
{
|
||||
size_t i;
|
||||
int used;
|
||||
|
||||
if (StackSizeCheck_myStack == NULL)
|
||||
return -BAD_FUNC_ARG;
|
||||
|
||||
for (i = 0; i < StackSizeCheck_stackSize; i++) {
|
||||
if (StackSizeCheck_myStack[i] != STACK_CHECK_VAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
used = StackSizeCheck_stackSize - i;
|
||||
printf("stack used = %d\n", used);
|
||||
printf("setting stack relative offset reference mark in %s to +%ld\n", funcname, (char *)(StackSizeCheck_myStack + StackSizeCheck_stackSize) - (char *)p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void)
|
||||
static WC_INLINE ssize_t StackSizeHWM(void)
|
||||
{
|
||||
size_t i;
|
||||
ssize_t used;
|
||||
@@ -2117,9 +2059,19 @@ static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void)
|
||||
}
|
||||
|
||||
used = StackSizeCheck_stackSize - i;
|
||||
if ((ssize_t)*StackSizeCheck_stackSizeHWM_ptr < used)
|
||||
*StackSizeCheck_stackSizeHWM_ptr = used;
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
static WC_INLINE ssize_t StackSizeHWM_OffsetCorrected(void)
|
||||
{
|
||||
ssize_t used = StackSizeHWM();
|
||||
if (used < 0)
|
||||
return used;
|
||||
if (StackSizeCheck_stackOffsetPointer)
|
||||
used -= (ssize_t)(((char *)StackSizeCheck_myStack + StackSizeCheck_stackSize) - (char *)StackSizeCheck_stackOffsetPointer);
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
@@ -2151,10 +2103,81 @@ int StackSizeHWMReset(void)
|
||||
})
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define STACK_SIZE_INIT() (void)StackSizeSetOffset(__builtin_frame_address(0))
|
||||
#define STACK_SIZE_INIT() (void)StackSizeSetOffset(__FUNCTION__, __builtin_frame_address(0))
|
||||
#endif
|
||||
|
||||
#endif /* DEBUG_STACK_SIZE_VERBOSE */
|
||||
#endif /* HAVE_STACK_SIZE_VERBOSE */
|
||||
|
||||
static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf)
|
||||
{
|
||||
size_t i;
|
||||
int ret;
|
||||
void* status;
|
||||
unsigned char* myStack = NULL;
|
||||
size_t stackSize = 1024*1024;
|
||||
pthread_attr_t myAttr;
|
||||
pthread_t threadId;
|
||||
|
||||
#ifdef PTHREAD_STACK_MIN
|
||||
if (stackSize < PTHREAD_STACK_MIN)
|
||||
stackSize = PTHREAD_STACK_MIN;
|
||||
#endif
|
||||
|
||||
ret = posix_memalign((void**)&myStack, sysconf(_SC_PAGESIZE), stackSize);
|
||||
if (ret != 0 || myStack == NULL)
|
||||
err_sys("posix_memalign failed\n");
|
||||
|
||||
XMEMSET(myStack, STACK_CHECK_VAL, stackSize);
|
||||
|
||||
ret = pthread_attr_init(&myAttr);
|
||||
if (ret != 0)
|
||||
err_sys("attr_init failed");
|
||||
|
||||
ret = pthread_attr_setstack(&myAttr, myStack, stackSize);
|
||||
if (ret != 0)
|
||||
err_sys("attr_setstackaddr failed");
|
||||
|
||||
#ifdef HAVE_STACK_SIZE_VERBOSE
|
||||
StackSizeCheck_stackSizeHWM = 0;
|
||||
{
|
||||
struct debug_stack_size_verbose_shim_args shim_args;
|
||||
shim_args.myStack = myStack;
|
||||
shim_args.stackSize = stackSize;
|
||||
shim_args.stackSizeHWM_ptr = &StackSizeCheck_stackSizeHWM;
|
||||
shim_args.fn = tf;
|
||||
shim_args.args = args;
|
||||
ret = pthread_create(&threadId, &myAttr, (thread_func)debug_stack_size_verbose_shim, (void *)&shim_args);
|
||||
}
|
||||
#else
|
||||
ret = pthread_create(&threadId, &myAttr, tf, args);
|
||||
#endif
|
||||
if (ret != 0) {
|
||||
perror("pthread_create failed");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = pthread_join(threadId, &status);
|
||||
if (ret != 0)
|
||||
err_sys("pthread_join failed");
|
||||
|
||||
for (i = 0; i < stackSize; i++) {
|
||||
if (myStack[i] != STACK_CHECK_VAL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(myStack);
|
||||
#ifdef HAVE_STACK_SIZE_VERBOSE
|
||||
printf("stack used = %lu\n", StackSizeCheck_stackSizeHWM);
|
||||
#else
|
||||
{
|
||||
size_t used = stackSize - i;
|
||||
printf("stack used = %lu\n", used);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (int)((size_t)status);
|
||||
}
|
||||
|
||||
#endif /* HAVE_STACK_SIZE */
|
||||
|
||||
|
Reference in New Issue
Block a user