ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

debug.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/ps/debug.c
00005  * PURPOSE:         Process Manager: Debugging Support (Set/Get Context)
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  *                  Thomas Weidenmueller (w3seek@reactos.org)
00008  */
00009 
00010 /* INCLUDES ****************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* PRIVATE FUNCTIONS *********************************************************/
00017 
00018 #if DBG
00019 VOID
00020 NTAPI
00021 PspDumpThreads(BOOLEAN IncludeSystem)
00022 {
00023     PLIST_ENTRY CurrentThread, CurrentProcess;
00024     PEPROCESS Process;
00025     PETHREAD Thread;
00026     ULONG nThreads = 0;
00027 
00028     /* Loop all Active Processes */
00029     CurrentProcess = PsActiveProcessHead.Flink;
00030     while(CurrentProcess != &PsActiveProcessHead)
00031     {
00032         /* Get the process */
00033         Process = CONTAINING_RECORD(CurrentProcess, EPROCESS, ActiveProcessLinks);
00034 
00035         /* Skip the Initial Process if requested */
00036         if((Process != PsInitialSystemProcess) ||
00037            (Process == PsInitialSystemProcess && IncludeSystem))
00038         {
00039             /* Loop all its threads */
00040             CurrentThread = Process->ThreadListHead.Flink;
00041             while(CurrentThread != &Process->ThreadListHead)
00042             {
00043 
00044                 /* Get teh Thread */
00045                 Thread = CONTAINING_RECORD(CurrentThread, ETHREAD, ThreadListEntry);
00046                 nThreads++;
00047 
00048                 /* Print the Info */
00049                 DbgPrint("State %d Affinity %08x Priority %d PID.TID %d.%d Name %.8s Stack: \n",
00050                          Thread->Tcb.State,
00051                          Thread->Tcb.Affinity,
00052                          Thread->Tcb.Priority,
00053                          Thread->Cid.UniqueProcess,
00054                          Thread->Cid.UniqueThread,
00055                          Thread->ThreadsProcess->ImageFileName);
00056 
00057                 /* Make sure it's not running */
00058                 if(Thread->Tcb.State == Ready ||
00059                    Thread->Tcb.State == Standby ||
00060                    Thread->Tcb.State == Waiting)
00061                 {
00062                     ULONG i = 0;
00063                     PULONG Esp = (PULONG)Thread->Tcb.KernelStack;
00064                     PULONG Ebp = (PULONG)Esp[4];
00065 
00066                     /* Print EBP */
00067                     DbgPrint("Ebp 0x%.8X\n", Ebp);
00068 
00069                     /* Walk it */
00070                     while(Ebp != 0 && Ebp >= (PULONG)Thread->Tcb.StackLimit)
00071                     {
00072                         /* Print what's on the stack */
00073                         DbgPrint("%.8X %.8X%s", Ebp[0], Ebp[1], (i % 8) == 7 ? "\n" : "  ");
00074                         Ebp = (PULONG)Ebp[0];
00075                         i++;
00076                     }
00077 
00078                     /* Print a new line if there's nothing */
00079                     if((i % 8) != 0) DbgPrint("\n");
00080                 }
00081 
00082                 /* Move to the next Thread */
00083                 CurrentThread = CurrentThread->Flink;
00084             }
00085         }
00086 
00087         /* Move to the next Process */
00088         CurrentProcess = CurrentProcess->Flink;
00089     }
00090 }
00091 #endif
00092 
00093 /* PUBLIC FUNCTIONS **********************************************************/
00094 
00095 /*
00096  * @implemented
00097  */
00098 NTSTATUS
00099 NTAPI
00100 PsGetContextThread(IN PETHREAD Thread,
00101                    IN OUT PCONTEXT ThreadContext,
00102                    IN KPROCESSOR_MODE PreviousMode)
00103 {
00104     GET_SET_CTX_CONTEXT GetSetContext;
00105     ULONG Size = 0, Flags = 0;
00106     NTSTATUS Status;
00107 
00108     /* Enter SEH */
00109     _SEH2_TRY
00110     {
00111         /* Set default ength */
00112         Size = sizeof(CONTEXT);
00113 
00114         /* Read the flags */
00115         Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
00116 
00117 #ifdef _M_IX86
00118         /* Check if the caller wanted extended registers */
00119         if ((Flags & CONTEXT_EXTENDED_REGISTERS) !=
00120             CONTEXT_EXTENDED_REGISTERS)
00121         {
00122             /* Cut them out of the size */
00123             Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
00124         }
00125 #endif
00126 
00127         /* Check if we came from user mode */
00128         if (PreviousMode != KernelMode)
00129         {
00130             /* Probe the context */
00131             ProbeForWrite(ThreadContext, Size, sizeof(ULONG));
00132         }
00133     }
00134     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00135     {
00136         /* Return the exception code */
00137         _SEH2_YIELD(return _SEH2_GetExceptionCode());
00138     }
00139     _SEH2_END;
00140 
00141     /* Initialize the wait event */
00142     KeInitializeEvent(&GetSetContext.Event, NotificationEvent, FALSE);
00143 
00144     /* Set the flags and previous mode */
00145     GetSetContext.Context.ContextFlags = Flags;
00146     GetSetContext.Mode = PreviousMode;
00147 
00148     /* Check if we're running in the same thread */
00149     if (Thread == PsGetCurrentThread())
00150     {
00151         /* Setup APC parameters manually */
00152         GetSetContext.Apc.SystemArgument1 = NULL;
00153         GetSetContext.Apc.SystemArgument2 = Thread;
00154 
00155         /* Enter a guarded region to simulate APC_LEVEL */
00156         KeEnterGuardedRegion();
00157 
00158         /* Manually call the APC */
00159         PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
00160                                         NULL,
00161                                         NULL,
00162                                         &GetSetContext.Apc.SystemArgument1,
00163                                         &GetSetContext.Apc.SystemArgument2);
00164 
00165         /* Leave the guarded region */
00166         KeLeaveGuardedRegion();
00167 
00168         /* We are done */
00169         Status = STATUS_SUCCESS;
00170     }
00171     else
00172     {
00173         /* Initialize the APC */
00174         KeInitializeApc(&GetSetContext.Apc,
00175                         &Thread->Tcb,
00176                         OriginalApcEnvironment,
00177                         PspGetOrSetContextKernelRoutine,
00178                         NULL,
00179                         NULL,
00180                         KernelMode,
00181                         NULL);
00182 
00183         /* Queue it as a Get APC */
00184         if (!KeInsertQueueApc(&GetSetContext.Apc, NULL, Thread, 2))
00185         {
00186             /* It was already queued, so fail */
00187             Status = STATUS_UNSUCCESSFUL;
00188         }
00189         else
00190         {
00191             /* Wait for the APC to complete */
00192             Status = KeWaitForSingleObject(&GetSetContext.Event,
00193                                            0,
00194                                            KernelMode,
00195                                            FALSE,
00196                                            NULL);
00197         }
00198     }
00199 
00200     _SEH2_TRY
00201     {
00202         /* Copy the context */
00203         RtlCopyMemory(ThreadContext, &GetSetContext.Context, Size);
00204     }
00205     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00206     {
00207         /* Get the exception code */
00208         Status = _SEH2_GetExceptionCode();
00209     }
00210     _SEH2_END;
00211 
00212     /* Return status */
00213     return Status;
00214 }
00215 
00216 /*
00217  * @implemented
00218  */
00219 NTSTATUS
00220 NTAPI
00221 PsSetContextThread(IN PETHREAD Thread,
00222                    IN OUT PCONTEXT ThreadContext,
00223                    IN KPROCESSOR_MODE PreviousMode)
00224 {
00225     GET_SET_CTX_CONTEXT GetSetContext;
00226     ULONG Size = 0, Flags = 0;
00227     NTSTATUS Status;
00228 
00229     /* Enter SEH */
00230     _SEH2_TRY
00231     {
00232         /* Set default length */
00233         Size = sizeof(CONTEXT);
00234 
00235         /* Read the flags */
00236         Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
00237 
00238 #ifdef _M_IX86
00239         /* Check if the caller wanted extended registers */
00240         if ((Flags & CONTEXT_EXTENDED_REGISTERS) !=
00241             CONTEXT_EXTENDED_REGISTERS)
00242         {
00243             /* Cut them out of the size */
00244             Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
00245         }
00246 #endif
00247 
00248         /* Check if we came from user mode */
00249         if (PreviousMode != KernelMode)
00250         {
00251             /* Probe the context */
00252             ProbeForRead(ThreadContext, Size, sizeof(ULONG));
00253         }
00254 
00255         /* Copy the context */
00256         RtlCopyMemory(&GetSetContext.Context, ThreadContext, Size);
00257     }
00258     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00259     {
00260         /* Return the exception code */
00261         _SEH2_YIELD(return _SEH2_GetExceptionCode());
00262     }
00263     _SEH2_END;
00264 
00265     /* Initialize the wait event */
00266     KeInitializeEvent(&GetSetContext.Event, NotificationEvent, FALSE);
00267 
00268     /* Set the flags and previous mode */
00269     GetSetContext.Context.ContextFlags = Flags;
00270     GetSetContext.Mode = PreviousMode;
00271 
00272     /* Check if we're running in the same thread */
00273     if (Thread == PsGetCurrentThread())
00274     {
00275         /* Setup APC parameters manually */
00276         GetSetContext.Apc.SystemArgument1 = UlongToPtr(1);
00277         GetSetContext.Apc.SystemArgument2 = Thread;
00278 
00279         /* Enter a guarded region to simulate APC_LEVEL */
00280         KeEnterGuardedRegion();
00281 
00282         /* Manually call the APC */
00283         PspGetOrSetContextKernelRoutine(&GetSetContext.Apc,
00284                                         NULL,
00285                                         NULL,
00286                                         &GetSetContext.Apc.SystemArgument1,
00287                                         &GetSetContext.Apc.SystemArgument2);
00288 
00289         /* Leave the guarded region */
00290         KeLeaveGuardedRegion();
00291 
00292         /* We are done */
00293         Status = STATUS_SUCCESS;
00294     }
00295     else
00296     {
00297         /* Initialize the APC */
00298         KeInitializeApc(&GetSetContext.Apc,
00299                         &Thread->Tcb,
00300                         OriginalApcEnvironment,
00301                         PspGetOrSetContextKernelRoutine,
00302                         NULL,
00303                         NULL,
00304                         KernelMode,
00305                         NULL);
00306 
00307         /* Queue it as a Get APC */
00308         if (!KeInsertQueueApc(&GetSetContext.Apc, UlongToPtr(1), Thread, 2))
00309         {
00310             /* It was already queued, so fail */
00311             Status = STATUS_UNSUCCESSFUL;
00312         }
00313         else
00314         {
00315             /* Wait for the APC to complete */
00316             Status = KeWaitForSingleObject(&GetSetContext.Event,
00317                                            0,
00318                                            KernelMode,
00319                                            FALSE,
00320                                            NULL);
00321         }
00322     }
00323 
00324     /* Return status */
00325     return Status;
00326 }
00327 
00328 NTSTATUS
00329 NTAPI
00330 NtGetContextThread(IN HANDLE ThreadHandle,
00331                    IN OUT PCONTEXT ThreadContext)
00332 {
00333     PETHREAD Thread;
00334     NTSTATUS Status;
00335     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00336     PAGED_CODE();
00337 
00338     /* Get the Thread Object */
00339     Status = ObReferenceObjectByHandle(ThreadHandle,
00340                                        THREAD_GET_CONTEXT,
00341                                        PsThreadType,
00342                                        PreviousMode,
00343                                        (PVOID*)&Thread,
00344                                        NULL);
00345 
00346     if (!NT_SUCCESS(Status)) return Status;
00347 
00348     /* Make sure it's not a system thread */
00349     if (Thread->SystemThread)
00350     {
00351         /* Fail */
00352         Status = STATUS_INVALID_HANDLE;
00353     }
00354     else
00355     {
00356         /* Call the kernel API */
00357         Status = PsGetContextThread(Thread, ThreadContext, PreviousMode);
00358     }
00359 
00360     /* Dereference it and return */
00361     ObDereferenceObject(Thread);
00362     return Status;
00363 }
00364 
00365 NTSTATUS
00366 NTAPI
00367 NtSetContextThread(IN HANDLE ThreadHandle,
00368                    IN PCONTEXT ThreadContext)
00369 {
00370     PETHREAD Thread;
00371     NTSTATUS Status;
00372     KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
00373     PAGED_CODE();
00374 
00375     /* Get the Thread Object */
00376     Status = ObReferenceObjectByHandle(ThreadHandle,
00377                                        THREAD_SET_CONTEXT,
00378                                        PsThreadType,
00379                                        PreviousMode,
00380                                        (PVOID*)&Thread,
00381                                        NULL);
00382 
00383     if (!NT_SUCCESS(Status)) return Status;
00384 
00385     /* Make sure it's not a system thread */
00386     if (Thread->SystemThread)
00387     {
00388         /* Fail */
00389         Status = STATUS_INVALID_HANDLE;
00390     }
00391     else
00392     {
00393         /* Call the kernel API */
00394         Status = PsSetContextThread(Thread, ThreadContext, PreviousMode);
00395     }
00396 
00397     /* Dereference it and return */
00398     ObDereferenceObject(Thread);
00399     return Status;
00400 }
00401 
00402 /* EOF */

Generated on Sat May 26 2012 04:16:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.