Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c9a1ff6e
Commit
c9a1ff6e
authored
Oct 16, 2023
by
Paul Gofman
Committed by
Alexandre Julliard
Oct 17, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll/tests: Add test for collided unwind.
parent
2a893f42
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
91 additions
and
15 deletions
+91
-15
exception.c
dlls/ntdll/tests/exception.c
+91
-15
No files found.
dlls/ntdll/tests/exception.c
View file @
c9a1ff6e
...
...
@@ -3030,9 +3030,9 @@ static const struct exception
static
int
got_exception
;
static
void
run_exception_test
(
void
*
handler
,
const
void
*
context
,
static
void
run_exception_test
_flags
(
void
*
handler
,
const
void
*
context
,
const
void
*
code
,
unsigned
int
code_size
,
DWORD
access
)
DWORD
access
,
DWORD
handler_flags
)
{
unsigned
char
buf
[
8
+
6
+
8
+
8
];
RUNTIME_FUNCTION
runtime_func
;
...
...
@@ -3045,7 +3045,7 @@ static void run_exception_test(void *handler, const void* context,
runtime_func
.
UnwindData
=
0x1000
;
unwind
->
Version
=
1
;
unwind
->
Flags
=
UNW_FLAG_EHANDLER
;
unwind
->
Flags
=
handler_flags
;
unwind
->
SizeOfProlog
=
0
;
unwind
->
CountOfCodes
=
0
;
unwind
->
FrameRegister
=
0
;
...
...
@@ -3072,6 +3072,13 @@ static void run_exception_test(void *handler, const void* context,
VirtualProtect
(
code_mem
,
code_size
,
oldaccess
,
&
oldaccess2
);
}
static
void
run_exception_test
(
void
*
handler
,
const
void
*
context
,
const
void
*
code
,
unsigned
int
code_size
,
DWORD
access
)
{
run_exception_test_flags
(
handler
,
context
,
code
,
code_size
,
access
,
UNW_FLAG_EHANDLER
);
}
static
DWORD
WINAPI
handler
(
EXCEPTION_RECORD
*
rec
,
ULONG64
frame
,
CONTEXT
*
context
,
DISPATCHER_CONTEXT
*
dispatcher
)
{
...
...
@@ -4962,25 +4969,93 @@ static DWORD nested_exception_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGISTRAT
return
ExceptionContinueExecution
;
}
static
void
test_nested_exception
(
void
)
static
const
BYTE
nested_except_code
[]
=
{
static
const
BYTE
except_code
[]
=
{
0xe8
,
0x02
,
0x00
,
0x00
,
0x00
,
/* call nest */
0x90
,
/* nop */
0xc3
,
/* ret */
/* nest: */
0xcc
,
/* int3 */
0x90
,
/* nop */
0xc3
,
/* ret */
};
0xe8
,
0x02
,
0x00
,
0x00
,
0x00
,
/* call nest */
0x90
,
/* nop */
0xc3
,
/* ret */
/* nest: */
0xcc
,
/* int3 */
0x90
,
/* nop */
0xc3
,
/* ret */
};
static
void
test_nested_exception
(
void
)
{
got_nested_exception
=
got_prev_frame_exception
=
FALSE
;
run_exception_test
(
nested_exception_handler
,
NULL
,
except_code
,
ARRAY_SIZE
(
except_code
),
PAGE_EXECUTE_READ
);
run_exception_test
(
nested_exception_handler
,
NULL
,
nested_except_code
,
ARRAY_SIZE
(
nested_
except_code
),
PAGE_EXECUTE_READ
);
ok
(
got_nested_exception
,
"Did not get nested exception.
\n
"
);
ok
(
got_prev_frame_exception
,
"Did not get nested exception in the previous frame.
\n
"
);
}
static
unsigned
int
collided_unwind_exception_count
;
static
DWORD
collided_exception_handler
(
EXCEPTION_RECORD
*
rec
,
EXCEPTION_REGISTRATION_RECORD
*
frame
,
CONTEXT
*
context
,
EXCEPTION_REGISTRATION_RECORD
**
dispatcher
)
{
CONTEXT
ctx
;
trace
(
"collided_exception_handler Rip %p, Rsp %p, code %#lx, flags %#lx, ExceptionAddress %p, frame %p.
\n
"
,
(
void
*
)
context
->
Rip
,
(
void
*
)
context
->
Rsp
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
frame
);
switch
(
collided_unwind_exception_count
++
)
{
case
0
:
/* Initial exception from nested_except_code. */
ok
(
rec
->
ExceptionCode
==
STATUS_BREAKPOINT
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
nested_exception_initial_frame
=
frame
;
/* Start unwind. */
pRtlUnwindEx
((
char
*
)
nested_exception_initial_frame
+
8
,
(
char
*
)
code_mem
+
5
,
NULL
,
NULL
,
&
ctx
,
NULL
);
ok
(
0
,
"shouldn't be reached
\n
"
);
break
;
case
1
:
ok
(
rec
->
ExceptionCode
==
STATUS_UNWIND
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
rec
->
ExceptionFlags
==
EH_UNWINDING
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
((
char
*
)
context
->
Rip
==
(
char
*
)
code_mem
+
7
,
"got %p.
\n
"
,
rec
->
ExceptionAddress
);
/* generate exception in unwind handler. */
RaiseException
(
0xdeadbeef
,
0
,
0
,
0
);
ok
(
0
,
"shouldn't be reached
\n
"
);
break
;
case
2
:
/* Inner call frame, continue search. */
ok
(
rec
->
ExceptionCode
==
0xdeadbeef
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
!
rec
->
ExceptionFlags
||
rec
->
ExceptionFlags
==
EXCEPTION_SOFTWARE_ORIGINATE
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
(
frame
==
nested_exception_initial_frame
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
break
;
case
3
:
/* Top level call frame, handle exception by unwinding. */
ok
(
rec
->
ExceptionCode
==
0xdeadbeef
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
!
rec
->
ExceptionFlags
||
rec
->
ExceptionFlags
==
EXCEPTION_SOFTWARE_ORIGINATE
,
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
((
char
*
)
frame
==
(
char
*
)
nested_exception_initial_frame
+
8
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
pRtlUnwindEx
((
char
*
)
nested_exception_initial_frame
+
8
,
(
char
*
)
code_mem
+
5
,
NULL
,
NULL
,
&
ctx
,
NULL
);
ok
(
0
,
"shouldn't be reached
\n
"
);
break
;
case
4
:
/* Collided unwind. */
ok
(
rec
->
ExceptionCode
==
STATUS_UNWIND
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
rec
->
ExceptionFlags
==
(
EH_UNWINDING
|
EH_COLLIDED_UNWIND
),
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
(
frame
==
nested_exception_initial_frame
,
"got %p, expected %p.
\n
"
,
frame
,
nested_exception_initial_frame
);
break
;
case
5
:
/* EH_COLLIDED_UNWIND cleared for the following frames. */
ok
(
rec
->
ExceptionCode
==
STATUS_UNWIND
,
"got %#lx.
\n
"
,
rec
->
ExceptionCode
);
ok
(
rec
->
ExceptionFlags
==
(
EH_UNWINDING
|
EH_TARGET_UNWIND
),
"got %#lx.
\n
"
,
rec
->
ExceptionFlags
);
ok
((
char
*
)
frame
==
(
char
*
)
nested_exception_initial_frame
+
8
,
"got %p, expected %p.
\n
"
,
frame
,
(
char
*
)
nested_exception_initial_frame
+
8
);
break
;
}
return
ExceptionContinueSearch
;
}
static
void
test_collided_unwind
(
void
)
{
got_nested_exception
=
got_prev_frame_exception
=
FALSE
;
collided_unwind_exception_count
=
0
;
run_exception_test_flags
(
collided_exception_handler
,
NULL
,
nested_except_code
,
ARRAY_SIZE
(
nested_except_code
),
PAGE_EXECUTE_READ
,
UNW_FLAG_EHANDLER
|
UNW_FLAG_UHANDLER
);
ok
(
collided_unwind_exception_count
==
6
,
"got %u.
\n
"
,
collided_unwind_exception_count
);
}
static
CONTEXT
test_unwind_apc_context
;
static
BOOL
test_unwind_apc_called
;
...
...
@@ -11561,6 +11636,7 @@ START_TEST(exception)
test_wow64_context
();
test_kiuserexceptiondispatcher
();
test_nested_exception
();
test_collided_unwind
();
if
(
pRtlAddFunctionTable
&&
pRtlDeleteFunctionTable
&&
pRtlInstallFunctionTableCallback
&&
pRtlLookupFunctionEntry
)
test_dynamic_unwind
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment