summaryrefslogtreecommitdiffstats
path: root/private/ntos/rtl/excptdbg.c
blob: d4e303f63bd339e18fcd41ece4e0700945bf4f59 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    excpdbg.c

Abstract:

    This module implements an exception dispatcher logging facility

Author:

    Kent Forschmiedt (kentf) 05-Oct-1995

Revision History:

--*/

#include "ntrtlp.h"

PLAST_EXCEPTION_LOG RtlpExceptionLog;
ULONG RtlpExceptionLogCount;
ULONG RtlpExceptionLogSize;


VOID
RtlInitializeExceptionLog(
    IN ULONG Entries
    )
/*++

Routine Description:

    This routine allocates space for the exception dispatcher logging
    facility, and records the address and size of the log area in globals
    where they can be found by the debugger.

    If memory is not available, the table pointer will remain NULL
    and the logging functions will do nothing.

Arguments:

    Entries - Supplies the number of entries to allocate for

Return Value:

    None

--*/
{
#if defined(NTOS_KERNEL_RUNTIME)
    RtlpExceptionLog = (PLAST_EXCEPTION_LOG)ExAllocatePoolWithTag( NonPagedPool, sizeof(LAST_EXCEPTION_LOG) * Entries, 'gbdE' );
#else
    //RtlpExceptionLog = (PLAST_EXCEPTION_LOG)RtlAllocateHeap( RtlProcessHeap(), 0, sizeof(LAST_EXCEPTION_LOG) * Entries );
#endif
    if (RtlpExceptionLog) {
        RtlpExceptionLogSize = Entries;
    }
}


ULONG
RtlpLogExceptionHandler(
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PCONTEXT ContextRecord,
    IN ULONG ControlPc,
    IN PVOID HandlerData,
    IN ULONG Size
    )
/*++

Routine Description:

    Records the dispatching of exceptions to frame-based handlers.
    The debugger may inspect the table later and interpret the data
    to discover the address of the filters and handlers.

Arguments:

    ExceptionRecord - Supplies an exception record

    ContextRecord - Supplies the context at the exception

    ControlPc - Supplies the PC where control left the frame being
        dispatched to.

    HandlerData - Supplies a pointer to the host-dependent exception
        data.  On the RISC machines this is a RUNTIME_FUNCTION record;
        on x86 it is the registration record from the stack frame.

    Size - Supplies the size of HandlerData

Returns:

    The index to the log entry used, so that if the handler returns
    a disposition it may be recorded.

--*/
{
#if !defined(NTOS_KERNEL_RUNTIME)

    return 0;

#else

    ULONG LogIndex;

    if (!RtlpExceptionLog) {
        return 0;
    }

    ASSERT(Size <= MAX_EXCEPTION_LOG_DATA_SIZE * sizeof(ULONG));

    do {
        LogIndex = RtlpExceptionLogCount;
    } while ((PVOID)LogIndex != InterlockedCompareExchange(
                                    (PVOID*)&RtlpExceptionLogCount,
                                    (PVOID)((LogIndex + 1) % MAX_EXCEPTION_LOG),
                                    (PVOID)LogIndex));

    //
    // the debugger will have to interpret the exception handler
    // data, because it cannot be done safely here.
    //

    RtlCopyMemory(RtlpExceptionLog[LogIndex].HandlerData,
                  HandlerData,
                  Size);
    RtlpExceptionLog[LogIndex].ExceptionRecord = *ExceptionRecord;
    RtlpExceptionLog[LogIndex].ContextRecord = *ContextRecord;
    RtlpExceptionLog[LogIndex].Disposition = -1;

    return LogIndex;
#endif  // !NTOS_KERNEL_RUNTIME
}


VOID
RtlpLogLastExceptionDisposition(
    ULONG LogIndex,
    EXCEPTION_DISPOSITION Disposition
    )
/*++

Routine Description:

    Records the disposition from an exception handler.

Arguments:

    LogIndex - Supplies the entry number of the exception log record.

    Disposition - Supplies the disposition code

Return Value:

    None

--*/

{
    // If MAX_EXCEPTION_LOG or more exceptions were dispatched while
    // this one was being handled, this disposition will get written
    // on the wrong record.  Oh well.
    if (RtlpExceptionLog) {
        RtlpExceptionLog[LogIndex].Disposition = Disposition;
    }
}