2015-06-05 13 views
6

, bu uygulama: hayır C çalışma zamanı ile 64-bit uygulama olarak Visual Studio 2010 yılında inşaCRT'siz uygulamalarınm neden başlangıçta kesintiye uğruyor? Örneğin

#define _WIN32_WINNT 0x0500 

#include <windows.h> 

int __stdcall NoCRTMain(void) 
{ 
    int result; 

    PWSTR lpCmdLine = GetCommandLine(); 

    for (;;) 
    { 
     if (*lpCmdLine == L'"') 
     { 
      lpCmdLine++; 
      for (;;) 
      { 
       if (*lpCmdLine == L'"') break; 
       if (*lpCmdLine == L'\0') break; 
       lpCmdLine++; 
      } 
     } 
     if (*lpCmdLine == L' ') break; 
     if (*lpCmdLine == L'\0') break; 
     lpCmdLine++; 
    } 

    while (*lpCmdLine == ' ') lpCmdLine++; 

    result = MessageBox(NULL, lpCmdLine, L"Scripting Engine", MB_OK | MB_SYSTEMMODAL); 

    if (result != IDOK) for (;;) Sleep(INFINITE); 

    ExitProcess(0); 
} 

, bu mükemmel çalışıyor - çoğu zaman. Bazen başlangıçta kolayca ortaya çıkan bir sebepten dolayı çökmeye başlayacaktır. Bu kilitlenme, uygulamadaki kodun çalıştırılmasından önce gerçekleşir (aşağıya bakın). Sorun oluştuğunda, yalnızca yürütülebilir dosyanın belirli bir örneğinde, yani belirli bir yürütülebilir dosyada gerçekleşir. Dosyanın bir byte-byte özdeş kopyası normal olarak çalışır. Bilgisayar yeniden başlatıldığında sorun (olacak mı?) Ortadan kalkar. Sorunu güvenilir bir şekilde yeniden üretmeye çalışmak için testler yapıyorum, bu nedenle, örneğin Visual Studio yüklü ise, sorunun oluşabileceği koşulları belirleyebilir miyim? Sadece anti-virüs yüklü ise? Ama şimdiye kadar, problemi, dilsiz şanstan başka bir yöntemle çoğaltmakta pek başarılı olamadım.

Çoğu zaman, hata ayıklama, kernel32! BaseThreadInitThunk dosyasının NoCRTMain adresi yerine geçersiz bir adresi çağırdığını gösteriyor, ancak bazı son çalıştırmalar, DLL'leri yüklerken görünüşte daha önce başarısız olmuş olsa da.

Modül yüklendiğinde, ImageBase'in yanlış ayarlandığından sorunu takip ettiğime inanıyorum. Çalışan bir örneği, çalıştırılabilir modülüne 0x00D8 göreli bir bellek dökümü, winnt.h gelen yapı _IMAGE_OPTIONAL_HEADER64 üzerinde:

00000001`3f5900d8 0b 02 0a 00 00 02 00 00 00 06 00 00 00 00 00 00 
00000001`3f5900e8 00 10 00 00 00 10 00 00 00 00 59 3f 01 00 00 00 

ImageBase (son sekiz bayt), modülün başlangıç ​​adresini içerdiğini göstermektedir bu dava 1`3f590000. Başarısız örneğinde, aynı bellek
00000001`3fc600d8 0b 02 0a 00 00 02 00 00 00 06 00 00 00 00 00 00 
00000001`3fc600e8 00 10 00 00 00 10 00 00 00 00 8f 3f 01 00 00 00 

ImageBase yerine beklendiği gibi 1`3fc60000 olmaktan çok, 1`3f8f0000 olduğunu gösterir dökümü.

Bu, bir hata ayıklayıcının işlemi inceleyebildiği en erken noktadan önce gerçekleşiyor gibi görünüyor, bu yüzden nasıl devam edeceğimi bilmiyorum. Belki de çekirdek hata ayıklaması yapmalı mıyım? Şu anda problemi sergileyen bir VMWare vSphere sanal makinesine sahibim ve geri dönebileceğim bir anlık görüntü var, bu yüzden denemeyi göze alabilirim.

Yani:

  • kimse bu davranışının nedenini biliyor mu ve daha da önemlisi, nasıl önleneceği?

  • Bellek dökümü ile ilgili yorumum yanlış mı?

  • Hata ayıklama/sorun giderme önerileri?

Derleyici seçenekleri:

/Zi /nologo /W3 /WX- /O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_WINDOWS" 
/D "_UNICODE" /D "UNICODE" /Gm- /EHsc /MT /GS- /Gy /fp:precise /Zc:wchar_t 
/Zc:forScope /Fp"x64\Release\sehalt.pch" /Fa"x64\Release\" /Fo"x64\Release\" 
/Fd"x64\Release\vc100.pdb" /Gd /errorReport:queue 

Bağlayıcı seçenekleri:

/OUT:"C:\documents\code\w7lab-scripting\sehalt\x64\Release\sehalt.exe" 
/INCREMENTAL:NO /NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" 
"winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" 
"oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /NODEFAULTLIB 
/MANIFEST /ManifestFile:"x64\Release\sehalt.exe.intermediate.manifest" 
/ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG 
/PDB:"C:\documents\code\w7lab-scripting\sehalt\x64\Release\sehalt.pdb" 
/SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF 
/PGD:"C:\documents\code\w7lab-scripting\sehalt\x64\Release\sehalt.pgd" 
/LTCG /TLBID:1 /ENTRY:"NoCRTMain" /DYNAMICBASE /NXCOMPAT 
/MACHINE:X64 /ERRORREPORT:QUEUE 

Not: Bu şekilde başarısız olmuş bilinir ve hangilerinin benim uygulamalarının hangi bakarak, değil Sorunun yalnızca bir sayfadan (4096 bayt) daha küçük olan yürütülebilirler için oluştuğundan şüphelenir.

+0

Re: _ "(? Edecektir) normal şekilde çalışmaya başlar dosyanın bir bayt-bayt özdeş kopyası sorun bilgisayar yeniden başlatıldığında kaybolabilir." _ Sorun kesinlikle içinde bulunması gerekmez düşündürdü kaynak kodunuz, ama belki de bağlantı/loader işlemi ile. Bazı bilgileri, yürütülebilir eksik tahmin bazı parametre (bazen yanlış) ve önbelleğe alma "tahmin" zorunda OS'nin yükleyici lider olduğunu belirtti olabilir. – stakx

+0

Kodunuzu nasıl derler ve bağlarsınız? Sorunuza ilgili ayarları/komut satırını ekleyebilir misiniz? – stakx

+0

@stakx: teşekkürler; Derleyici ve linker komut satırlarını ekledim. –

cevap

1

Bir yıl sonra, Hans'ın önerisinin mükemmel bir şekilde çalıştığını iddia ederek kendime güveniyorum: uygulama, /DYNAMICBASE:NO ve /FIXED:YES seçenekleriyle oluşturulmuşsa, sorun oluşmaz.

İlgili konular