  | 
					  | 
					  |  
					
					
	
    
 | 
                  
                    | 
                    | 					
				  
				            
					            
						            
							            
								            | 
									            
								             | 
            								
								            
									            
	Windows内核调试
	帖子发起人: zyq8709   发起时间: 2011-06-21 09:18 上午   回复: 13
	
	
 
 
	 
		
			
				
					
						
							
							   
							
   
							
							
						 | 
						
						    
						      
						        | 
							          帖子排序: 
							            
						         | 
						        
							          
							          
						         | 
						       
						     
						 | 
					 
				 
			 | 
		 
	 
	
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-21, 09:18 上午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
											  | 
											
												
													
														
															
																 
																
																	Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢!已经迷茫了,求解答! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
我看到有些地方说在dispatch级上调用等待函数,会导致当前线程挂起并会引起线程切换,由于在dispatch级,所以无法切换线程,所以会导致死锁并崩溃。
 请看一些代码:
 KEVENT e;
 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)
 {
 unsigned i;
 for (i = 0; i MajorFunction<img src="/emoticons/emotion-55.gif" alt="Idea [I]" /> = qqDefaultHandler;
 DriverObject->MajorFunction[IRP_MJ_CREATE] = qqCreateClose;
 	DriverObject->MajorFunction[IRP_MJ_CLOSE] = qqCreateClose;
 	DriverObject->MajorFunction[IRP_MJ_PNP] = qqPnP;
 
 	DriverObject->DriverUnload = qqUnload;
 	DriverObject->DriverStartIo = NULL;
 	DriverObject->DriverExtension->AddDevice = qqAddDevice;
 
 	return STATUS_SUCCESS;
 }
 
 void qqUnload(IN PDRIVER_OBJECT DriverObject)
 {
 	KeSetEvent(&e,IO_NO_INCREMENT,FALSE);
 }
 void f()
 {
 	KIRQL o;
 	_asm int 3
     KeRaiseIrql(DISPATCH_LEVEL,&o);
 	
 	KeInitializeEvent(&e,NotificationEvent,FALSE);
 	_asm int 3
 	KeWaitForSingleObject(&e,Executive,KernelMode,FALSE,0);
 	_asm int 3
 	_asm int 3
 	PsTerminateSystemThread(STATUS_SUCCESS);
 }
 NTSTATUS qqAddDevice(IN PDRIVER_OBJECT  DriverObject, IN PDEVICE_OBJECT  PhysicalDeviceObject)
 {
 	PDEVICE_OBJECT DeviceObject = NULL;
 	Pqq_DEVICE_EXTENSION pExtension = NULL;
 	NTSTATUS status;
 	HANDLE h;
 	status = IoCreateDevice(DriverObject,
 						    sizeof(qq_DEVICE_EXTENSION),
 							NULL,
 							FILE_DEVICE_UNKNOWN,
 							0,
 							0,
 							&DeviceObject);
 
 	if (!NT_SUCCESS(status))
 		return status;
 
 	pExtension = (Pqq_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
 	pExtension->DeviceObject = DeviceObject;
 	pExtension->PhysicalDeviceObject = PhysicalDeviceObject;
 	pExtension->TargetDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
 
 	status = IoRegisterDeviceInterface(PhysicalDeviceObject, &GUID_qqInterface, NULL, &pExtension->DeviceInterface);
 	ASSERT(NT_SUCCESS(status));
 
 	DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 	_asm int 3
 	PsCreateSystemThread(&h,0,NULL,NtCurrentProcess(),0,(PKSTART_ROUTINE)f,0);
 	return STATUS_SUCCESS;
 }
 在AddDevice例程中创建一个线程f,然后提升其IRQL为dispatch级,并等待事件,并在Unload例程中设置事件。可有些奇怪的是在f中等待事件并未导致崩溃死锁,而系统运转一切正常,f线程也正常挂起,其余在系统中想做什么都可以,并未受到阻碍。反而是在Unload例程执行并设置事件之后,f线程并未得到执行,反而引起了蓝屏崩溃。
 另:我看到KeWaitForSingleObject内发现调用了KeRaiseIrqlToDpcLevel,而在Dispatch级这是没问题的,然后就在此级别上进行了线程切换,按理在Dispatch级上都没问题,WDK文档却规定等待函数在timeout==null时只能低于dispatch,但是在调试跟踪中dispatch级别也没问题,这不是两者矛盾吗,这到底是怎么回事?在dispatch级上调用等待函数会出现什么问题?
 请问到底这是怎么一回事,请帮我解答一下吧,多谢!!!
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-22, 22:03 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
请张老师给予指点,请再顺便看看另外几个问题吧,多谢了!
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 11:56 上午
                        
											 | 
										 
										
											
												
													 
													
														王宇
													
													
														 
														
  
  
														 注册: 2007-05-08
														
														 发 贴: 306
														
													
											  | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 12:01 下午
                        
											 | 
										 
										
											
												
													 
													
														格蠹老雷
													
													
														 
														
  
														 注册: 2005-12-19
														
														 发 贴: 1,303
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 12:08 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
											  | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
张老师您好,我是一个毕业生,自学的计算机,现在在复习考研。看了您的书,感觉学到了许多。
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 12:55 下午
                        
											 | 
										 
										
											
												
													 
													
														格蠹老雷
													
													
														 
														
  
														 注册: 2005-12-19
														
														 发 贴: 1,303
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
思考的很深入,这个问题的确值得深究,根本的问题是NT的scheduler运行在DISPATCH_LEVEL,把蓝屏的dump压缩一下发上来看看
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 13:28 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
											  | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																 
	附件: 代码及dump.rar
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
	
	
	
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
	
	张老师您好,调试环境是VMware加XP SP2。我理解的的调度器也就是一段运行在Dispatch级上的KiSwapThread例程,无论是KfLowerIrql还是KeWaitForSingleObject都是先提升Irql再调用KiSwapContext导致线程切换,感觉也就是一段简单的函数调用,没有什么特别之处,至于说调度器只是一个形象的说法。请各位老师再看一看我发现的另一个关于KfLowerIrql调用时违例却无错误发生的问题(http://advdbg.org/forums/4961/ShowPost.aspx),应该和这个问题有一定联系。
 附件为代码和dump文件。
	
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 14:10 下午
                        
											 | 
										 
										
											
												
													 
													
														王宇
													
													
														 
														
  
  
														 注册: 2007-05-08
														
														 发 贴: 306
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
	
	
	
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
	
	刚才正要回你的蓝屏问题就被叫去吃饭了,回来看到你的 dump,和我想的一样。你的蓝屏是必然的。
 
 qqUnload 置完事件就 Unload 了整个驱动,此时线程 f 还未得到执行。等线程再被调度,地址已不可用:
 
 STACK_TEXT:  
 b1f11da4 00000000 b1f11ddc 805c5a28 00000000 [Unloaded_qq.sys]+0x5d9  /*论坛会转义尖括号*/
 
 注意这个 Unloaded_
 
 PS : Debugman 太水了,楼主可以不用去了~
	
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 14:17 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
											  | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
	
	
	
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
	
	多谢王老师的解答,确实是在执行一个收回的地址,所以出错。 那么如果我不在Unload例程中设置事件,而是在其他派遣函数中设置也就是在没被卸载的驱动中执行,是不是就不会出错了? 那么对于KeWaitForSingleObject对Irql级别的要求又该怎么解释呢? 
	
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 16:32 下午
                        
											 | 
										 
										
											
												
													 
													
														格蠹老雷
													
													
														 
														
  
														 注册: 2005-12-19
														
														 发 贴: 1,303
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
	
	
	
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
	
	看了下目前的源代码,改变IRQL的代码有问题:             
                KeRaiseIrql(DISPATCH_LEVEL,&o);
 	_asm int 3
 	KeLowerIrql(o);
 	_asm int 3
 	KeLowerIrql(DISPATCH_LEVEL);
 后面两次调用是何目的?如DDK所言:
 It is a fatal error to call KeLowerIrql using an input NewIrql that was not returned by the immediately preceding call to KeRaiseIrql.
 按道理来说,对于单CPU的系统,一旦以个CPU被提升到DISPATCH_LEVEL,那么整个系统的GUI就失去响应了,因为CPU没有机会执行普通线程了
	
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 17:02 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
											  | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
	
	
	
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
	
	张老师,我这样是有用意的。
 第一次降低是正常的,第二次我用一个高于当前的Irql来降低目的是为了观察KfLowerIrql对于这种错误的处理,但是我发现并未出现任何错误,而且当前Irql被改为了Dispatch级,然后在该级别上调用KeWaitForSingleObject来观察错误,同样的是等待函数中每一步都被执行了,而且也正常的进入了KiSwapThread和KiSwapContext,并切换了上下文进入了另一个线程,然后再观察系统,一切如常。如果只是一个CPU核心被阻塞,那么我再加载一次驱动安装一个设备,一切仍然如常。我CPU是双核的,但是加载了两次按理说就算是阻塞,也是两个都被阻塞了,然而系统该怎么操作都没有问题,这十分奇怪,并与公认的说法相违背,请各位老师再费心了!
	
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-23, 18:02 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																 
		附件: 修改后的代码与截图.rar
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
		
		
		
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
		
		我按照王老师的指导修改了代码,只是将设置事件放到了IRP_MJ_CREATE派遣函数,其他的包括违例的IRQL使用都没改,结果竟然一点问题都没了,难道MS关于IRQL的文档说明有问题,请各位老师关注一下,多谢了!
 修改后的代码与运行截图见附件。
		
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-26, 10:46 上午
                        
											 | 
										 
										
											
												
													 
													
														格蠹老雷
													
													
														 
														
  
														 注册: 2005-12-19
														
														 发 贴: 1,303
														
													
											  | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
		
		
		
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
		
		看了下新的代码,不是把有问题的两次KeLowerIrql去掉了么?这样的话,CPU应该挂在DISPATCH_LEVEL,不会去执行调度器,也就是没有机会执行普通线程,如果看栈回溯,那么很可能看到如下的场景:
 
 kd> knL
  # ChildEBP RetAddr  
 00 980f9b88 82e96362 nt!KeAccumulateTicks+0x3c5
 01 980f9bc8 82e9620f nt!KeUpdateRunTime+0x145
 02 980f9c20 82e9b597 nt!KeUpdateSystemTime+0x613
 03 980f9c20 82e9244c nt!KeUpdateSystemTimeAssist+0x13
 04 980f9d0c 99601907 nt!KeWaitForSingleObject+0x510
 05 980f9d50 830396bb RealBug!WaitAtHighIrqlThread+0xd7
 06 980f9d90 82eeb0f9 nt!PspSystemThreadStartup+0x9e
 07 00000000 00000000 nt!KiThreadStartup+0x19
 
 #0-3表示CPU是在响应时钟中断,此时的IRQL如果为0,那么CPU便可以调度普通线程了,但是现在为2。如果在调试会话中,那么NT可能会发出这样一个调试信息:
 Assertion: *** DPC watchdog timeout
     This is NOT a break in update time
     This is most likely a BUG in an ISR
     Perform a stack trace to find the culprit
     The period will be doubled on continuation
     Use gh to continue!!
 
 DDK中的很多说法是“法规性”的规则,触犯了不一定立刻蓝屏,但是可能导致间接的严重问题,比如系统挂死,在DISPATCH_LEVEL等待就属于这种情况。
 在检查版本的NT中,有一个ASSERT来检查当前的IRQL,而free版本的没有这个检查。但是问题是一样的,进入等待后便没有办法唤醒这个线程了...
 
		
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
			
				
					
						
							
								
									
										
											
												
												 
                            2011-06-27, 17:42 下午
                        
											 | 
										 
										
											
												
													 
													
														zyq8709
													
													
														 
														
  
														 注册: 2011-04-19
														
														 发 贴: 74
														
													
												 
											 | 
											
												
													
														
															
																
																
																	Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢! 
																
															
														 | 
													 
													
														| 
														  
														 | 
													 
												 
												
		
		
		
											 | 
										 
										
											
												
													
														
															 
														 | 
														
															
																
																	
																		
		
		十分感谢张老师的回答,我刚才看了一下,我把代码发错了,我调试的不是这个版本,而是带有那两个错误调用的。
 张老师的回答让我有些清醒了,但是我还有一些疑问:就是KeWaitForSingleObject调用之后会调用KiSwapThread例程来切换线程,为何会引发时钟中断来切换线程?
 是不是在时钟中断中还有对Irql级别的判断,超过了2就不会进行线程调度?
 多谢张老师了!
 
		
																		 
																	 | 
																 
															 
														 | 
													 
													
														| 
															
														 | 
														
															IP 地址: 已记录  
														 | 
														
															报告
														 | 
													 
												 
											 | 
										 
									 
								 | 
							 
						 
					 | 
				 
			 
		
	
	
		
			| 
				高端调试 » 软件调试 » Windows内核调试 » Re: Dispatch_level及以上不能调用KeWaitForSingleObject的真正原因是什么?请张老师给予指点,多谢!
			 | 
			
				
			 | 
		 
	 
	
		
		
		 
		
								             | 
                                              | 					
								            
									            
								             | 
							             
						             
					             
				             
			          
                     |