Windows服务运行时发生异常,仅在Vista上运行

时间:2014-02-24 16:45:55

标签: c++ windows-services windbg

我有一个第三方内核模式驱动程序,由我用C ++编写的Windows服务控制。服务初始化代码似乎运行得很好,但是当运行服务线程时,它会遇到一个异常,表明堆栈或堆损坏(根据调试的情况而有所不同)。例外情况发生在“不在任何已加载模块中”的地址中,因此几乎不可能分辨出发生了什么。使用应用程序验证程序作为管理员在windbg中运行,在分析-v:

之后给出
Breakpoint 0 hit
eax=001ffb04 ebx=7ffda000 ecx=001ffb04 edx=002e1b34 esi=00000000 edi=001ff8a4
eip=00282051 esp=001ff76c ebp=001ff8b4 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000282
MyService!CServiceBase::Run+0x71:
00282051 8bf4            mov     esi,esp
0:000> g
Detected memory leaks!
Dumping objects ->
{53} normal block at 0x058BFFF0, 8 bytes long.
 Data: <  (     > C0 15 28 00 04 FB 1F 00 
Object dump complete.
(4e6c.4e9c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=7ffda000 ecx=bffefce9 edx=002f8950 esi=00000000 edi=001ff8a4
eip=bfe1045d esp=001ff778 ebp=001ff8b4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
bfe1045d ??              ???

_crtdbg“内存泄漏”我认为是在服务初始化期间分配的对象,在服务停止之前不会被释放。

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

Current verifier stop:
APPLICATION_VERIFIER_LUAPRIV_OK_OBJECT_DUMP (3317)
The application was able to access the object's security descriptor.
The application was granted the requested access to this object. A standard user should also be able to access this object. 
Arguments:
Arg1: 6d101d5c, Object Name 
Arg2: 0012019f, Access Requested 
Arg3: 05156f60, Security Descriptor 
Arg4: 05986fa0, String Security Descriptor 

Previous verifier stop:
APPLICATION_VERIFIER_LUAPRIV_OK_OBJECT_GRANT (331e)
Safe Object.
The application opened an object (such as a file or registry key) and requested access that is granted to at least one non-privileged entity (listed). This suggests that the same operation will work when attempted by non-privileged/standard users. 
Arguments:
Arg1: 6d101d5c, Object Type 
Arg2: 05148fd8, Object Name 
Arg3: 05156f8c, Access Control Entry 
Arg4: 00000000, N/A 
*** WARNING: Unable to verify checksum for ...nfapi.dll

FAULTING_IP: 
+0
bfe1045d ??              ???

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: bfe1045d
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: bfe1045d
Attempt to read from address bfe1045d

FAULTING_THREAD:  00004e9c

DEFAULT_BUCKET_ID:  BAD_INSTRUCTION_PTR

PROCESS_NAME:  MyService.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  bfe1045d

READ_ADDRESS:  bfe1045d 

FOLLOWUP_IP: 
MyService!main+71 [.....svc.cpp @ 51]
00282d81 83c404          add     esp,4

FAILED_INSTRUCTION_ADDRESS: 
+9
bfe1045d ??              ???

NTGLOBALFLAG:  2000100

APPLICATION_VERIFIER_FLAGS:  80c43267

APP:  myservice.exe

IP_ON_HEAP:  7ffda000
The fault address in not in any loaded module, please check your build's rebase
log at <releasedir>\bin\build_logs\timebuild\ntrebase.log for module which may
contain the address if it were loaded.

PRIMARY_PROBLEM_CLASS:  BAD_INSTRUCTION_PTR

BUGCHECK_STR:  APPLICATION_FAULT_BAD_INSTRUCTION_PTR_INVALID_POINTER_READ

FRAME_ONE_INVALID: 1

LAST_CONTROL_TRANSFER:  from 7ffda000 to bfe1045d

STACK_TEXT:  
WARNING: Frame IP not in any known module. Following frames may be wrong.
001ff774 7ffda000 cccccccc cccccccc cccccccc 0xbfe1045d
001ff8b4 00282d81 001ffb04 bfe107a5 00000000 0x7ffda000
001ffb4c 002aac69 00000001 05868fa8 0586af60 MyService!main+0x71
001ffb98 002aab2f 001ffbac 75fbd2e9 7ffda000 MyService!__tmainCRTStartup+0x129
001ffba0 75fbd2e9 7ffda000 001ffbec 77691603 MyService!mainCRTStartup+0xf
001ffbac 77691603 7ffda000 762ef334 00000000 KERNEL32!BaseThreadInitThunk+0xe
001ffbec 776915d6 002aab20 7ffda000 00000000 ntdll!__RtlUserThreadStart+0x23
001ffc04 00000000 002aab20 7ffda000 00000000 ntdll!_RtlUserThreadStart+0x1b


FAULTING_SOURCE_LINE:  .....svc.cpp

FAULTING_SOURCE_FILE:  .....svc.cpp

FAULTING_SOURCE_LINE_NUMBER:  51

FAULTING_SOURCE_CODE:  
    47: {
    48:     try
    49:     {
    50:         CSampleService service(SVCNAME, TRUE, TRUE, TRUE);
>   51:         if (!CServiceBase::Run(service))
    52:         {
    53:             printf("Service failed to run w/err 0x%08lx\n", GetLastError());
    54:         }
    55:         return 0;
    56:     } catch (char *str )


SYMBOL_STACK_INDEX:  2

SYMBOL_NAME:  myservice!main+71

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: MyService

IMAGE_NAME:  MyService.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  530b8caa

STACK_COMMAND:  ~0s ; kb

FAILURE_BUCKET_ID:  BAD_INSTRUCTION_PTR_c0000005_MyService.exe!main

BUCKET_ID:  APPLICATION_FAULT_BAD_INSTRUCTION_PTR_INVALID_POINTER_READ_BAD_IP_myservice!main+71

Followup: MachineOwner
---------

这里的困难是Windows服务启动代码无法直接调试,您必须跳过服务启动代码并进入初始化代码。服务启动后,您可以附加到要调试的进程,但是在服务成功启动之后但在初始化代码完成之后抛出此异常。如果我超过初始化代码的结尾,调用堆栈只是十六进制地址,代码是在ntdll.dll中汇编。我可以看到内存中的某些内容已被破坏,后来在服务运行中使用但我无法检测到这是什么,所有本地和全局变量在初始化代码中看起来都是正确的。第三方代码作为exe成功运行,如果我不调用第三方代码,服务将成功启动。 从命令行运行时,服务启动超时,如果发生异常,则可能会发生。

int main(int argc, char *argv[]) 
{
    try
    {
        CSampleService service(SVCNAME, TRUE, TRUE, TRUE);
        if (!CServiceBase::Run(service))
        {
            printf("Service failed to run w/err 0x%08lx\n", GetLastError());
        }
        return;
    } catch (char *str )
    {
        char sMessage[MAX_PATH];
        sprintf_s(sMessage,"Service failed to run, exception=%s", str);
        SvcReportEvent(sMessage, 0);
    }
    catch (...)
    {
        char sMessage[MAX_PATH];
        sprintf_s(sMessage,"Service failed to run, exception occured");
        SvcReportEvent(sMessage, 0);
    }
} 
编辑:我现在已经解决了这个问题。我在postportem模式下使用Windbg(HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Image File Execution Options \ servicename.exe 调试器(字符串)设置为“C:\ Program Files \ Debugging Tools for Windows(x86)\ windbg.exe”),通过ORING SERVICE_INTERACTIVE_PROCESS将服务类型设置为交互式。我使用__debugbreak()语句进入ServiceMain中的调试器,这会调出一个奇怪的全屏模式窗口,只有在“交互模式提示”对话框后运行windbg。在那里,我能够在启动后立即调试正在运行的服务。原来,服务确实有一个错误导致堆栈溢出,我能够看到并纠正。谢谢大家!

0 个答案:

没有答案