ReactOS  0.4.15-dev-1039-gb9754fa
stacktrace.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS API tests
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Test for RtlQueryProcessBackTraceInformation & RtlLogStackBackTrace
5  * COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #include "loadconfig.h"
9 
10 
11 // This test serves 2 purposes:
12 // 1. It tests RtlQueryProcessBackTraceInformation & RtlLogStackBackTrace
13 // 2. It tests the correct activation of IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (see also common.c)
14 
16 
17 
18 // Seems that this struct is wrong in our sdk?
20 {
27 
28 
31 
33 PVOID GetFunctionAddress()
34 {
35  return _ReturnAddress();
36 }
37 
39 USHORT Call_Backtrace_2()
40 {
41  USHORT Index;
43  ok(Index != 0, "RtlLogStackBackTrace failed\n");
44  return Index;
45 }
46 
47 
49 USHORT Call_Backtrace_1()
50 {
51  USHORT Index;
52  // It seems that the function calling RtlLogStackBackTrace is skipped,
53  // so we wrap it in a deeper nested function to be able to check it
54  g_Call_Address = GetFunctionAddress();
56  Index = Call_Backtrace_2();
57  return Index;
58 }
59 
60 static void Check_Stacktrace(PVOID* BackTrace, USHORT Depth)
61 {
62  ok(Depth > 2, "Unexpected Depth: %lu\n", (ULONG)Depth);
63  if (Depth > 2)
64  {
65  ULONG_PTR EndAddress = ((ULONG_PTR)g_Call_Address + 0x20);
66  ok(BackTrace[0] >= g_Call_Address && (ULONG_PTR)BackTrace[0] < EndAddress,
67  "Unexpected return: %p, expected between %p and %p\n", BackTrace[0], g_Call_Address, (PVOID)EndAddress);
68  ok(BackTrace[1] == g_PreviousReturnAddress, "Unexpected return: %p, expected: %p\n",
69  BackTrace[1], g_PreviousReturnAddress);
70  }
71 }
72 
74 {
76  USHORT StackTrace;
77  PRTL_PROCESS_BACKTRACES Backtraces;
78  ULONG OldNumberOfBackTraces, n;
80  int found = 0;
81 
84  if (Status != STATUS_SUCCESS)
85  return;
86 
87  Backtraces = Buffer1->BackTraces;
88  ok(Backtraces != NULL, "No BackTraces\n");
89  if (!Backtraces)
90  return;
91 
92  OldNumberOfBackTraces = Backtraces->NumberOfBackTraces;
93  // Capture a stacktrace
94  StackTrace = Call_Backtrace_1();
95 
96  // Show that the old debugbuffer is not changed
97  ok(OldNumberOfBackTraces == Backtraces->NumberOfBackTraces, "Debug buffer changed! (%lu => %lu)\n",
98  OldNumberOfBackTraces, Backtraces->NumberOfBackTraces);
99 
100  // Ask for a new snapshot
103  if (Status != STATUS_SUCCESS)
104  return;
105 
106  Backtraces = Buffer2->BackTraces;
107  ok(Backtraces != NULL, "No BackTraces\n");
108  if (!Backtraces)
109  return;
110 
111  ok(OldNumberOfBackTraces+1 == Backtraces->NumberOfBackTraces, "Stacktrace not added! (%lu => %lu)\n",
112  OldNumberOfBackTraces, Backtraces->NumberOfBackTraces);
113 
114  FirstBacktrace = (PRTL_PROCESS_BACKTRACE_INFORMATION_32)&Backtraces->BackTraces[0];
115  trace("NumberOfBackTraces=%lu\n", Backtraces->NumberOfBackTraces);
116  for (n = 0; n < Backtraces->NumberOfBackTraces; ++n)
117  {
118  PRTL_PROCESS_BACKTRACE_INFORMATION_32 Info = FirstBacktrace + n;
119 #if 0
120  USHORT j;
121 
122  trace("BackTraces[%02lu]->SymbolicBackTrace = %p\n", n, Info->SymbolicBackTrace);
123  trace("BackTraces[%02lu]->TraceCount = %lu\n", n, Info->TraceCount);
124  trace("BackTraces[%02lu]->Index = %lu\n", n, (ULONG)Info->Index);
125  trace("BackTraces[%02lu]->Depth = %lu\n", n, (ULONG)Info->Depth);
126  for (j = 0; j < Info->Depth; ++j)
127  {
128  trace("BackTraces[%02lu]->BackTrace[%02u] = %p\n", n, j, Info->BackTrace[j]);
129  }
130  trace("\n");
131 #endif
132  if (Info->Index == StackTrace)
133  {
134  found = 1;
135  Check_Stacktrace(Info->BackTrace, Info->Depth);
136  }
137  }
138  ok(found, "Stacktrace not found :(\n");
139 }
140 
141 
142 START_TEST(stacktrace)
143 {
144  PRTL_DEBUG_INFORMATION Buffer1, Buffer2;
145 
146  if (!check_loadconfig())
147  return;
148 
149  skip("QueryBacktrace not implemented yet\n");
150  return;
151 
152  Buffer1 = RtlCreateQueryDebugBuffer(0, FALSE);
153  ok(Buffer1 != NULL, "Failed!\n");
154  if (Buffer1)
155  {
156  Buffer2 = RtlCreateQueryDebugBuffer(0, FALSE);
157  ok(Buffer2 != NULL, "Failed!\n");
158  if (Buffer2)
159  {
160  test_QueryBacktrace(Buffer1, Buffer2);
162  }
163 
165  }
166 }
#define IN
Definition: typedefs.h:39
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:814
LONG NTSTATUS
Definition: precomp.h:26
GLdouble n
Definition: glext.h:7729
NTSYSAPI PRTL_DEBUG_INFORMATION NTAPI RtlCreateQueryDebugBuffer(_In_ ULONG Size, _In_ BOOLEAN EventPair)
Definition: dbgbuffer.c:66
#define ok_hex(expression, result)
Definition: atltest.h:94
struct TraceInfo Info
NTSTATUS NTAPI RtlQueryProcessBackTraceInformation(IN OUT PRTL_DEBUG_INFORMATION Buffer)
RTL_PROCESS_BACKTRACE_INFORMATION BackTraces[1]
Definition: rtltypes.h:1171
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define noinline
Definition: types.h:60
NTSYSAPI USHORT NTAPI RtlLogStackBackTrace(VOID)
static void Check_Stacktrace(PVOID *BackTrace, USHORT Depth)
Definition: stacktrace.c:60
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
static void test_QueryBacktrace(PRTL_DEBUG_INFORMATION Buffer1, PRTL_DEBUG_INFORMATION Buffer2)
Definition: stacktrace.c:73
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
static PVOID g_PreviousReturnAddress
Definition: stacktrace.c:30
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static PVOID g_Call_Address
Definition: stacktrace.c:29
PRTL_PROCESS_BACKTRACES BackTraces
Definition: rtltypes.h:1203
#define trace
Definition: atltest.h:70
static const UCHAR Index[8]
Definition: usbohci.c:18
NTSYSAPI NTSTATUS NTAPI RtlDestroyQueryDebugBuffer(IN PRTL_DEBUG_INFORMATION DebugBuffer)
START_TEST(stacktrace)
Definition: stacktrace.c:142
Status
Definition: gdiplustypes.h:24
struct _RTL_PROCESS_BACKTRACE_INFORMATION_32 RTL_PROCESS_BACKTRACE_INFORMATION_32
struct _RTL_PROCESS_BACKTRACE_INFORMATION_32 * PRTL_PROCESS_BACKTRACE_INFORMATION_32
unsigned short USHORT
Definition: pedump.c:61
#define ok(value,...)
Definition: atltest.h:57
BOOL check_loadconfig()
Definition: common.c:35
#define skip(...)
Definition: atltest.h:64
void * _ReturnAddress(void)
__declspec(noinline)
Definition: stacktrace.c:32
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
return STATUS_SUCCESS
Definition: btrfs.c:3014