diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in index 3b88897..43bdada 100644 --- a/dlls/ntdll/tests/Makefile.in +++ b/dlls/ntdll/tests/Makefile.in @@ -19,6 +19,7 @@ C_SRCS = \ rtl.c \ rtlbitmap.c \ rtlstr.c \ + signal.c \ string.c \ time.c diff --git a/dlls/ntdll/tests/signal.c b/dlls/ntdll/tests/signal.c new file mode 100644 index 0000000..deacdf2 --- /dev/null +++ b/dlls/ntdll/tests/signal.c @@ -0,0 +1,100 @@ +/* + * Unit test suite for functions in ntdll signal_*.c files + * + * Copyright 2011 Janne Hakonen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "ntdll_test.h" +#include + +/* function pointers */ +static USHORT (WINAPI *pRtlCaptureStackBackTrace)(ULONG, ULONG, PVOID *, ULONG *); + +/* function prototypes */ +static void test_pRtlCaptureStackBackTrace(void); +static BOOL get_back_trace_with_invalid_frame_pointer(void); +static void capture_stack_back_trace(void); + +/* Test function for RtlCaptureStackBackTrace. */ +static void test_pRtlCaptureStackBackTrace(void) +{ + ok(TRUE == get_back_trace_with_invalid_frame_pointer(), "get_back_trace_with_invalid_frame_pointer() failed\n" ); +} + +/* This function attempts to invalidify one frame pointer and then calls + * capture_stack_back_trace(). If all goes well TRUE is returned, + * but if SEH exception is thrown FALSE is returned instead. */ +static BOOL get_back_trace_with_invalid_frame_pointer(void) +{ + BOOL result = FALSE; + void **frame; + void *old; + + /* copy base pointer to frame */ + __asm__ ("movl %%ebp, %0\n\t" : "=r" (frame)); + + /* invalidify next frame pointer */ + old = *frame; + *frame = (void*)0xffffffff; + + __TRY + { + /* try to get back trace with invalid call stack, exception is thrown + if something breaks + */ + capture_stack_back_trace(); + result = TRUE; + } + __EXCEPT_ALL + { + trace("capture_stack_back_trace() threw SEH exception, returning FALSE\n"); + result = FALSE; + } + __ENDTRY + + *frame = old; + return result; +} + +/* This function just calls RtlCaptureStackBackTrace and doesn't return anything. */ +static void capture_stack_back_trace(void) +{ + ULONG framesToSkip = 1; + ULONG maxCallers = 62 - framesToSkip; + PULONG hash = NULL; + + void** callers = (void**) calloc(maxCallers, sizeof(void*)); + + pRtlCaptureStackBackTrace(framesToSkip, maxCallers, callers, hash); + + free(callers); +} + +START_TEST(signal) +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + pRtlCaptureStackBackTrace = (void *)GetProcAddress(mod, "RtlCaptureStackBackTrace"); + if (pRtlCaptureStackBackTrace) + { + test_pRtlCaptureStackBackTrace(); + } + else + { + win_skip("Required RtlCaptureStackBackTrace function is not available\n"); + } +} +