3

エラー レポートを返したアプリがあります。アプリは Delphi 2006 で作成されており、起動時にハングします。MadExcept のメイン スレッド スタックを以下に示します。デフォルトのプリンターはないと思われますが、ここで障害を再現することはできません。

MadExcept からのスタック ダンプ

この問題を見た人はいますか?

ユニット WWPrintToPrinterOrPDFRoutines の初期化部分

initialization
PagesRangeStartPage    := 1 ;
PagesRangeEndPage      := 999 ;
PrintRange             := prAll ;
PrintCopies            := 1 ;
PrintCollate           := false ;
InitialPrintPaperName  := 'A4' ;                                   

if (Printer.Printers.Count = 0) then    //  <--------- this causes the hang
    begin
    InitialPrintOrientation       := Printers.poPortrait ;
    end
else
    begin
    InitialPrintOrientation       := GetDefaultPrinterOrientation ;       
    InitialPrintPaperName         := GetDefaultPrinterPaperName ;         
    end ;

CurrentPreviewPage     := 1 ;
NDRMemoryStream        := TMemoryStream.Create ;

または逆アセンブル:

    WWPrintToPrinterOrPDFRoutines.pas.682: PagesRangeStartPage    := 1 ;
    007C4404 C705EC8B81000100 mov [$00818bec],$00000001
    WWPrintToPrinterOrPDFRoutines.pas.683: PagesRangeEndPage      := 999 ;
    007C440E C705F08B8100E703 mov [$00818bf0],$000003e7
    WWPrintToPrinterOrPDFRoutines.pas.684: PrintRange             := prAll ;
    007C4418 C605F48B810001   mov byte ptr [$00818bf4],$01
    WWPrintToPrinterOrPDFRoutines.pas.685: PrintCopies            := 1 ;
    007C441F C705F88B81000100 mov [$00818bf8],$00000001
    WWPrintToPrinterOrPDFRoutines.pas.686: PrintCollate           := false ;
    007C4429 C605FC8B810000   mov byte ptr [$00818bfc],$00
    WWPrintToPrinterOrPDFRoutines.pas.687: InitialPrintPaperName  := 'A4' ;
    007C4430 B8288C8100       mov eax,$00818c28
    007C4435 BAC0447C00       mov edx,$007c44c0
    007C443A E82D1AC4FF       call @LStrAsg
    WWPrintToPrinterOrPDFRoutines.pas.689: if (Printer.Printers.Count = 0) then
    007C443F E8B0BCCDFF       call Printer
    007C4444 E89FB7CDFF       call TPrinter.GetPrinters   <----- HANG OCCURS HERE
4

1 に答える 1

7

私はあなたのプログラムに何か問題があるとは思いませんし、これをハングさせないようにするためにあなたが変更できることは何もありません。そのシステムのOSレベルで問題が発生しています。

そのNdrClientCall2関数は、RPCおよびDCOM呼び出しを行うために使用されるリモートプロシージャコールネットワークデータ表現エンジンの一部です。

NtConnectPortは、ポートオブジェクト(ミューテックスやファイルハンドルなどの基本的なカーネルオブジェクト)を接続するための関数です。ポートは、LPCの最下位レベルのウィンドウで使用されます。

NtConnectPortへの呼び出しは、サーバーがNtCompleteConnectPortを呼び出すまでブロックされます(NtConnectPortへの呼び出しのタイムアウト処理はありません)。

したがって、問題は、winspool.drvが同じマシン上の別のプロセスへのLPC接続を確立しようとすることです(私の推測では、spoolsv.exe、プリンタースプーラーサービスですが、提供された情報からはわかりません)。ポート(NtCreatePort)を作成しましたが、その上でNtListenPortを呼び出していないか、NtListenPortが戻ったときにNtAcceptConnectPortおよびNtCompleteConnectPortを呼び出していません。これにより、プロセス内のNtConnectPortへの呼び出しがすべて返されるのを防ぎます。

したがって、実際の問題は、ポートの反対側が属するプロセスに関係なく、プロセスの外部にあります。

于 2011-04-18T02:19:43.087 に答える