7b565f0f5da69419cfec118928dcba0b2a47cf11
[reactos.git] / reactos / ntoskrnl / kd / dlog.c
1 /* $Id: dlog.c,v 1.2 2001/03/25 18:56:12 dwelch Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/kd/kdebug.c
6 * PURPOSE: Kernel debugger
7 * PROGRAMMER: Eric Kohl (ekohl@abo.rhein-zeitung.de)
8 * UPDATE HISTORY:
9 * 21/10/99: Created
10 */
11
12 /* INCLUDES ******************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ntoskrnl.h>
16 #include <internal/kd.h>
17 #include <ntos/minmax.h>
18
19 /* GLOBALS *******************************************************************/
20
21 #define DEBUGLOG_SIZE (32*1024)
22
23 #ifdef DBGPRINT_FILE_LOG
24
25 static CHAR DebugLog[DEBUGLOG_SIZE];
26 static ULONG DebugLogStart;
27 static ULONG DebugLogEnd;
28 static ULONG DebugLogCount;
29 static KSPIN_LOCK DebugLogLock;
30 static ULONG DebugLogOverflow;
31 static HANDLE DebugLogThreadHandle;
32 static CLIENT_ID DebugLogThreadCid;
33 static HANDLE DebugLogFile;
34 static KSEMAPHORE DebugLogSem;
35
36 #endif /* DBGPRINT_FILE_LOG */
37
38 /* FUNCTIONS *****************************************************************/
39
40 #ifdef DBGPRINT_FILE_LOG
41
42 VOID
43 DebugLogInit(VOID)
44 {
45 KeInitializeSpinLock(&DebugLogLock);
46 DebugLogStart = 0;
47 DebugLogEnd = 0;
48 DebugLogOverflow = 0;
49 DebugLogCount = 0;
50 KeInitializeSemaphore(&DebugLogSem, 0, 255);
51 }
52
53 NTSTATUS
54 DebugLogThreadMain(PVOID Context)
55 {
56 KIRQL oldIrql;
57 IO_STATUS_BLOCK Iosb;
58 static CHAR Buffer[256];
59 ULONG WLen;
60
61 for (;;)
62 {
63 KeWaitForSingleObject(&DebugLogSem,
64 0,
65 KernelMode,
66 FALSE,
67 NULL);
68 KeAcquireSpinLock(&DebugLogLock, &oldIrql);
69 while (DebugLogCount > 0)
70 {
71 if (DebugLogStart > DebugLogEnd)
72 {
73 WLen = min(256, DEBUGLOG_SIZE - DebugLogStart);
74 memcpy(Buffer, &DebugLog[DebugLogStart], WLen);
75 DebugLogStart =
76 (DebugLogStart + WLen) % DEBUGLOG_SIZE;
77 DebugLogCount = DebugLogCount - WLen;
78 KeReleaseSpinLock(&DebugLogLock, oldIrql);
79 NtWriteFile(DebugLogFile,
80 NULL,
81 NULL,
82 NULL,
83 &Iosb,
84 Buffer,
85 WLen,
86 NULL,
87 NULL);
88 }
89 else
90 {
91 WLen = min(256, DebugLogEnd - DebugLogStart);
92 memcpy(Buffer, &DebugLog[DebugLogStart], WLen);
93 DebugLogStart =
94 (DebugLogStart + WLen) % DEBUGLOG_SIZE;
95 DebugLogCount = DebugLogCount - WLen;
96 KeReleaseSpinLock(&DebugLogLock, oldIrql);
97 NtWriteFile(DebugLogFile,
98 NULL,
99 NULL,
100 NULL,
101 &Iosb,
102 Buffer,
103 WLen,
104 NULL,
105 NULL);
106 }
107 KeAcquireSpinLock(&DebugLogLock, &oldIrql);
108 }
109 KeReleaseSpinLock(&DebugLogLock, oldIrql);
110 }
111 }
112
113 VOID
114 DebugLogInit2(VOID)
115 {
116 NTSTATUS Status;
117 OBJECT_ATTRIBUTES ObjectAttributes;
118 UNICODE_STRING FileName;
119 IO_STATUS_BLOCK Iosb;
120
121 RtlInitUnicodeString(&FileName, L"\\SystemRoot\\debug.log");
122 InitializeObjectAttributes(&ObjectAttributes,
123 &FileName,
124 0,
125 NULL,
126 NULL);
127
128 Status = NtCreateFile(&DebugLogFile,
129 FILE_ALL_ACCESS,
130 &ObjectAttributes,
131 &Iosb,
132 NULL,
133 FILE_ATTRIBUTE_NORMAL,
134 0,
135 FILE_SUPERSEDE,
136 FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
137 NULL,
138 0);
139 if (!NT_SUCCESS(Status))
140 {
141 DbgPrint("Failed to create debug log file\n");
142 return;
143 }
144
145 Status = PsCreateSystemThread(&DebugLogThreadHandle,
146 THREAD_ALL_ACCESS,
147 NULL,
148 NULL,
149 &DebugLogThreadCid,
150 DebugLogThreadMain,
151 NULL);
152 }
153
154 VOID
155 DebugLogWrite(PCH String)
156 {
157 KIRQL oldIrql;
158
159 if (KeGetCurrentIrql() > DISPATCH_LEVEL)
160 {
161 DebugLogOverflow++;
162 return;
163 }
164
165 KeAcquireSpinLock(&DebugLogLock, &oldIrql);
166
167 if (DebugLogCount == DEBUGLOG_SIZE)
168 {
169 DebugLogOverflow++;
170 KeReleaseSpinLock(&DebugLogLock, oldIrql);
171 if (oldIrql < DISPATCH_LEVEL)
172 {
173 KeReleaseSemaphore(&DebugLogSem, IO_NO_INCREMENT, 1, FALSE);
174 }
175 return;
176 }
177
178 while ((*String) != 0)
179 {
180 DebugLog[DebugLogEnd] = *String;
181 String++;
182 DebugLogCount++;
183 if (DebugLogCount == DEBUGLOG_SIZE)
184 {
185 DebugLogOverflow++;
186 KeReleaseSpinLock(&DebugLogLock, oldIrql);
187 if (oldIrql < DISPATCH_LEVEL)
188 {
189 KeReleaseSemaphore(&DebugLogSem, IO_NO_INCREMENT, 1, FALSE);
190 }
191 return;
192 }
193 DebugLogEnd = (DebugLogEnd + 1) % DEBUGLOG_SIZE;
194 }
195
196 KeReleaseSpinLock(&DebugLogLock, oldIrql);
197 if (oldIrql < DISPATCH_LEVEL)
198 {
199 KeReleaseSemaphore(&DebugLogSem, IO_NO_INCREMENT, 1, FALSE);
200 }
201 }
202
203 #else /* not DBGPRINT_FILE_LOG */
204
205 VOID
206 DebugLogInit(VOID)
207 {
208 }
209
210 VOID
211 DebugLogInit2(VOID)
212 {
213 }
214
215 VOID
216 DebugLogWrite(PCH String)
217 {
218 }
219
220 #endif /* DBGPRINT_FILE_LOG */
221