Program yalnızca sürüm derlemesi olarak çöküyor - nasıl hata ayıklanır?


98

Burada "Schroedinger'ın Kedisi" tipi bir sorunum var - programım (aslında programım için test paketi, ancak yine de bir program) çöküyor, ancak yalnızca yayın modunda oluşturulmuşsa ve yalnızca komut satırından başlatıldığında . Mağara adamı hata ayıklama yoluyla (yani, her yerde kötü printf () mesajları), kodun çöktüğü test yöntemini belirledim, ancak ne yazık ki gerçek çökme, gördüğüm son izleme mesajlarının içinde olduğu için temiz bir şekilde çalışan diğer yıkıcılar.

Bu programı Visual Studio içinde çalıştırmayı denediğimde çökmüyor. WinDbg.exe'den başlatılırken de aynı şey geçerli. Kilitlenme yalnızca komut satırından başlatılırken meydana gelir. Bu, Windows Vista, btw altında gerçekleşiyor ve maalesef şu anda üzerinde test etmek için bir XP makinesine erişimim yok.

Windows'un bir yığın izi veya temiz bir şekilde çıkmış gibi programı sonlandırmaktan başka bir şey yazdırmasını sağlayabilirsem gerçekten güzel olurdu . Burada nasıl daha anlamlı bilgiler edinebileceğim ve umarım bu hatayı düzeltebileceğim konusunda herhangi bir tavsiyesi olan var mı?

Düzenleme: Sorun gerçekten de bu yazıda daha fazla açıkladığım sınır dışı bir diziden kaynaklanıyordu . Bu sorunu bulmadaki yardımlarınız için herkese teşekkürler!


O test yönteminden bir örnek verebilir misiniz?
akalenuk

Üzgünüz, kod kolayca buraya yapıştırılamayacak kadar karmaşık ve bahsettiğim gibi, test yönteminin kendisinde değil, daha sonra bir yıkıcı oluyor. Yine de, bu yöntemde başlatılmamış işaretçiler veya buna benzer bir şey yoktur.
Nik Reiman

3
Cevapların çoğu tahminlerden biraz daha fazlasıdır. Bir hata ayıklayıcı eklemeden çökmekte olan sürüm yapılarını analiz etmek için birkaç yaygın teknik vardır: stackoverflow.com/a/18513077/214777?stw=2
Sebastian

Belki bu sizin hatanız
Brent Bradburn

Yanıtlar:


132

Gördüğüm veya duyduğum vakaların% 100'ünde, bir C veya C ++ programının hata ayıklayıcıda düzgün çalıştığı, ancak dışarıda çalıştırıldığında başarısız olduğu durumlarda, neden bir işlev yerel dizisinin sonunu yazıyor. (Hata ayıklayıcı yığına daha fazlasını koyar, böylece önemli bir şeyin üzerine yazma olasılığınız azalır.)


33
Biri bu adama bir puro versin! Benim durumumda, yeterince büyük bir kapasiteye sahip olmayan bir StringBuilder'ı bir P / Invoke işlevine geçiriyordum. Sanırım, siz uyurken birisinin yüzünüze sihirli bir kalemle yazması gibi: hata ayıklayıcının altında, alnınızda karalama yapıyorlar, bu yüzden fark etmiyorsunuz, ancak hata ayıklayıcı olmadan, sizi göz ... onun gibi bir şey. Bu ipucu için teşekkürler!
Nicholas Piasecki

1
Benim durumumda, Obj-C kullanan bir ARM işlemcide bir hizalama sorunu olduğu ortaya çıktı.
Almo

1
11 yıl sonra ve bu hala doğru geliyor ... vektörlerinizi ayırmayı unutmayın.
dav

1
Tamam, öyleyse hata ayıklama modunun davranışı nasıl değiştirilir, böylece gerçekten hata ayıklanabilir.
Paul Childs

1
"Şimdi nereye bakılacağını bilmek" ama hata ayıklamada çalışan her şey sorunun nerede olduğunu nasıl söyler? Çoğu durumda cevabınızın doğru olduğunu ve neye bakmanız gerektiğini bilmek iyi bir başlangıç ​​olduğunu düşünmeme rağmen, sorunun tam olarak nerede olduğunu tam olarak belirlemek için büyük bir kod tabanında gezinmek çok pahalı olabilir.
Paul Childs

56

Daha önce bunun gibi sorunlarla karşılaştığımda, bu genellikle değişken başlatmadan kaynaklanıyordu. Hata ayıklama modunda, değişkenler ve işaretçiler otomatik olarak sıfırlanır, ancak yayın modunda başlatılmazlar. Bu nedenle, böyle bir kodunuz varsa

int* p;
....
if (p == 0) { // do stuff }

Hata ayıklama modunda, if'deki kod çalıştırılmaz, ancak yayınlama modunda p, 0 olma olasılığı düşük olan tanımlanmamış bir değer içerir, bu nedenle kod genellikle bir çökmeye neden olacak şekilde yürütülür.

Kodunuzu başlatılmamış değişkenler için kontrol ederdim. Bu, dizilerin içeriği için de geçerli olabilir.


Tipik durumlar, listeyi başlatan yapıcılar üyesine (birine) bir üye değişkeni koymayı unutur. Aynı etkiye sahiptir, ancak uygun üye başlatmayı aramanız gerektiğini bilmiyorsanız bulmak daha zordur.
steffenj

1
Hata ayıklama modunda değişkenler genellikle, değişkenin hangi durumda olduğunu göstermek için hata ayıklamada kullanılabilen bazı 'Derleyici Tanımlı sabit' olarak başlatılır. Örneğin: NULL veya 0xDeadBeef işaretçileri popülerdir.
Martin York

Hata ayıklama çalışma zamanları tipik olarak belleği sıfır olmayan bir değere başlatır, özellikle de NULL işaretçi testleri kodun işaretçi NULL değilmiş gibi davranmasına neden olur. Aksi takdirde, yayınlama modunu çökerten hata ayıklama modunda doğru şekilde çalışan kodunuz vardır.
Michael Burr

1
Hayır, değişkenler hiç başlatılmamış ve atanana kadar onları "kullanmak" hala UB'dir. Ancak, temeldeki bellek içerikleri genellikle 0x0000000 veya 0xDEADBEEF veya diğer tanınabilir kalıplarla önceden doldurulur.
Orbit'te Hafiflik Yarışları

27

Şimdiye kadar hiçbir yanıt, sürüm uygulamalarında hata ayıklama için mevcut teknikler hakkında ciddi bir genel bakış sunmaya çalışmadı:

  1. Yayınlama ve Hata Ayıklama yapıları birçok nedenden dolayı farklı davranır. İşte mükemmel bir genel bakış. Bu farklılıkların her biri, Debug yapısında bulunmayan Sürüm yapısında bir hataya neden olabilir.

  2. Bir hata ayıklayıcının varlığı , hem yayınlama hem de hata ayıklama yapıları için bir programın davranışını da değiştirebilir . Bu cevaba bakın. Kısacası, en azından Visual Studio Debugger, bir programa eklendiğinde Debug Heap'i otomatik olarak kullanır. _NO_DEBUG_HEAP ortam değişkenini kullanarak hata ayıklama yığınını kapatabilirsiniz. Bunu bilgisayar özelliklerinizde veya Visual Studio'daki Proje Ayarları'nda belirtebilirsiniz. Bu, hata ayıklayıcı eklenmiş olarak çökmeyi tekrarlanabilir hale getirebilir.

    Yığın bozulmasında hata ayıklama hakkında daha fazla bilgiyi burada bulabilirsiniz.

  3. Önceki çözüm işe yaramazsa, işlenmemiş istisnayı yakalamanız ve çökmenin meydana geldiği durumda bir ölüm sonrası hata ayıklayıcı eklemeniz gerekir . Bunun için örneğin WinDbg'yi kullanabilirsiniz, ölüm sonrası hata ayıklayıcılar hakkında ayrıntılar ve MSDN'de bunların kurulumu

  4. İstisna işleme kodunuzu geliştirebilirsiniz ve bu bir üretim uygulamasıysa şunları yapmalısınız:

    a. Kullanarak özel bir sonlandırma işleyicisi kurunstd::set_terminate

    Bu sorunu yerel olarak hata ayıklamak istiyorsanız, sonlandırma işleyicisinin içinde sonsuz bir döngü çalıştırabilir ve std::terminateçağrıldığını size bildirmek için konsola bazı metinler gönderebilirsiniz . Ardından hata ayıklayıcıyı ekleyin ve çağrı yığınını kontrol edin. Ya da yığın izlemesini bu yanıtta açıklandığı gibi yazdırırsınız.

    Bir üretim uygulamasında, ideal olarak sorunu burada açıklandığı gibi analiz etmenize olanak tanıyan küçük bir bellek dökümü ile birlikte eve bir hata raporu göndermek isteyebilirsiniz .

    b. Microsoft'un hem donanım hem de yazılım istisnalarını yakalamanıza izin veren yapılandırılmış istisna işleme mekanizmasını kullanın . MSDN'ye bakın . SEH kullanarak kodunuzun bazı kısımlarını koruyabilir ve problemde hata ayıklamak için a) ile aynı yaklaşımı kullanabilirsiniz. SEH, bir üretim uygulamasından bir hata raporu gönderirken kullanabileceğiniz istisna hakkında daha fazla bilgi verir.


16

Dikkat edilecek şeyler:

Dizi taşmaları - görsel stüdyo hata ayıklayıcı, çökmeleri durdurabilecek dolgu ekler.

Yarış koşulları - dahil olan birden fazla iş parçacığı var mı, öyleyse bir yarış koşulu çoğu yalnızca bir uygulama doğrudan yürütüldüğünde ortaya çıkıyor.

Bağlama - yayın yapınızın doğru kitaplıkları çekmesidir.

Denenecek şeyler:

Minidump - kullanımı gerçekten çok kolay (sadece msdn'de bakın) size her iş parçacığı için tam bir çökme dökümü verecektir. Çıktıyı görsel stüdyoya yüklersiniz ve sanki çökme anında hata ayıklıyormuşsunuz gibi.


1
Merhaba - Bu cevap için isimsiz bir olumsuz oylama yaptım. Nedenini anlamak isterim?
morechilli

12

WinDbg'yi ölüm sonrası hata ayıklayıcınız olarak ayarlayabilirsiniz. Bu, hata ayıklayıcıyı başlatacak ve çökme meydana geldiğinde işleme ekleyecektir. Ölüm sonrası hata ayıklama amacıyla WinDbg'yi kurmak için / I seçeneğini kullanın ( büyük harfle yazıldığını unutmayın ):

windbg /I

Daha fazla ayrıntı burada .

Sebebe gelince, diğer cevapların da önerdiği gibi büyük olasılıkla birimsel bir değişkendir.


2
Ve varsayılan olmasa da, derleyicinin yayın sürümleri için bile PDB dosyaları oluşturmasını sağlayabileceğinizi unutmayın.
Michael Burr

Gerçekten sorunun tek gerçek cevabı.
Sebastian

10

Saatlerce hata ayıklamadan sonra, nihayet sorunun nedenini buldum, ki bu aslında bir arabellek taşmasının neden olduğu tek bir bayt farkına neden oldu:

char *end = static_cast<char*>(attr->data) + attr->dataSize;

Bu bir çit direği hatasıdır (tek bir hata) ve şu şekilde düzeltildi:

char *end = static_cast<char*>(attr->data) + attr->dataSize - 1;

İşin garibi, kodumun çeşitli kısımlarının etrafına _CrtCheckMemory () için birkaç çağrı koymam ve her zaman 1. döndürdüler. "Return false" koyarak sorunun kaynağını bulabildim; test senaryosunu çağırır ve sonunda deneme yanılma yoluyla hatanın nerede olduğunu belirler.

Yorumlarınız için herkese teşekkürler - Bugün windbg.exe hakkında çok şey öğrendim! :)


8
Bugün benzer bir problemde hata ayıklama yapıyorum ve _CrtCheckMemory () her zaman 1. döndürüyordu. Ama sonra nedenini anladım: Release modunda, _CrtCheckMemory # ((int) 1) olarak tanımlanmıştır.
Brian Morearty

7

Exe'nizi bir sürüm olarak oluşturmuş olsanız bile, izlemeyi yığınlamanıza ve sınırlı miktarda değişken inceleme yapmanıza izin verecek PDB (Program veritabanı) dosyaları üretmeye devam edebilirsiniz. Yapı ayarlarınızda PDB dosyalarını oluşturma seçeneği vardır. Bunu açın ve yeniden bağlanın. Ardından, çökmeyi alıp almadığınızı görmek için önce IDE'den koşmayı deneyin. Eğer öyleyse, o zaman harika - her şeye bakmaya hazırsınız. Değilse, komut satırından çalıştırırken iki şeyden birini yapabilirsiniz:

  1. EXE'yi çalıştırın ve çökmeden önce İşleme Ekle (Visual Studio'da Araçlar menüsü) yapın.
  2. Çökmeden sonra, hata ayıklayıcıyı başlatma seçeneğini seçin.

PDB dosyalarını göstermeniz istendiğinde, onları bulmak için göz atın. PDB'ler, EXE veya DLL'lerinizle aynı çıktı klasörüne yerleştirildiyse, muhtemelen otomatik olarak alınacaktır.

PDB'ler, yığın izlerini, değişkenleri vb. Görmeyi mümkün kılmak için yeterli sembol bilgisine sahip kaynağa bir bağlantı sağlar. Değerleri normal olarak inceleyebilirsiniz, ancak optimizasyon geçişi yalnızca bir şeyler ifade edebileceğinden yanlış okumalar alabileceğinizi unutmayın. kayıtlarda görünür veya işler beklediğinizden farklı bir sırada gerçekleşir.

NB: Burada bir Windows / Visual Studio ortamı varsayıyorum.


3

Bunun gibi çökmelere neredeyse her zaman neden olur çünkü bir IDE genellikle başlatılmamış değişkenin içeriğini sıfır, null veya başka bir 'mantıklı' değere ayarlar, oysa yerel olarak çalıştırırken sistemin aldığı rastgele çöpleri alırsınız.

Bu nedenle, hatanız, neredeyse kesin olarak, doğru şekilde başlatılmadan önce bir işaretçi kullanıyormuşsunuz gibi bir şey kullanıyor olmanız ve IDE'de bundan kurtulmanızın çünkü tehlikeli bir yere işaret etmemesidir - ya da değeri sizin tarafınızdan ele alınır. hata kontrolü - ancak bırakma modunda kötü bir şey yapıyor.


3

Analiz edebileceğiniz bir kilitlenme dökümüne sahip olmak için:

  1. Kodunuz için pdb dosyaları oluşturun.
  2. Exe ve dll'lerinizin aynı adreste yüklenmesi için yeniden taban alırsınız.
  3. Dr. Watson gibi ölüm sonrası hata ayıklayıcıyı etkinleştirin
  4. Çökme bulucu gibi bir araç kullanarak çökme arızalarının adresini kontrol edin .

Windows için Hata Ayıklama araçları içindeki araçları da kontrol etmelisiniz . Uygulamayı izleyebilir ve ikinci şans istisnanızdan önceki tüm ilk şans istisnalarını görebilirsiniz.

Umarım yardımcı olur...


3

Bunun gibi bir hatayı ayıklamanın harika bir yolu, hata ayıklama yapınız için optimizasyonları etkinleştirmektir.


Operasyonun sorunu, hata ayıklayıcının çok yavaş olması değil, yalnızca yayın modunda çökmesidir.
reece

2

Bir zamanlar uygulama sizinkine benzer şekilde davrandığında bir sorun yaşadım. Sprintf'te kötü bir tampon taşması olduğu ortaya çıktı. Doğal olarak, bir hata ayıklayıcı eklenmiş olarak çalıştırıldığında çalıştı. Yaptığım şey, işlenmeyen bir istisna filtresi ( SetUnhandledExceptionFilter içinde sonsuza kadar engellediğim (INFINITE zaman aşımı değerine sahip sahte bir WaitForSingleObject kullanarak) ) .

Böylece şu satırlarda bir şey yapabilirsiniz:

long __stdcall MyFilter (EXCEPTION_POINTERS *)
{
    HANDLE hEvt = :: CreateEventW (0,1,0,0);
    eğer (hEvt)
    {
        eğer (WAIT_FAILED == :: WaitForSingleObject (hEvt, INFINITE))
        {
            // günlük hatası
        }
    }

}
// wmain / WinMain'inizde bir yerde:
SetUnhandledExceptionFilter (MyFilter);

Hata kendini gösterdikten sonra hata ayıklayıcıyı ekledim (gui programı yanıt vermeyi durdurdu).

O zaman ya bir çöplük alıp onunla daha sonra çalışabilirsiniz:

.dump / ma path_to_dump_file

Veya hemen hata ayıklayın. En basit yol, işlemci bağlamının çalışma zamanı istisna işleme makinesi tarafından kaydedildiği yeri izlemektir:

sd esp Aralığı 1003f

Komut, aramanın uzunluğu sağlandığında CONTEXT kayıtları için yığın adres alanını arayacaktır. Genellikle 'l? 10000' gibi bir şey kullanırım . Dikkat edin, peşinde olduğunuz kayıt olarak genellikle ele alınmayan istisna filtre çerçevesinin yakınında olağan dışı büyük sayılar kullanmayın. 1003f işlemci durumunu yakalamak için kullanılan bayrakların (CONTEXT_FULL'a karşılık geldiğine inanıyorum) kombinasyonudur. Aramanız şuna benzer görünecektir:

0: 000> sd esp l1000 1003f
0012c160 0001003f 00000000 00000000 00000000? ...............

Sonuçları geri aldığınızda, cxr komutundaki adresi kullanın:

.cxr 0012c160

Bu sizi tam olarak kilitlenme anında bu yeni BAĞLAM'a götürecektir (uygulamanızın çöktüğü anda tam olarak yığın izini alacaksınız). Ek olarak şunları kullanın:

.exr -1

tam olarak hangi istisnanın meydana geldiğini bulmak için.

Umarım yardımcı olur.


2

Bazen bu, önemli bir işlemi "assert" makrosunun içine sardığınız için olur. Bildiğiniz gibi, "assert" ifadeleri yalnızca hata ayıklama modunda değerlendirir.


1

Tanılama bilgilerini alma sorunlarınızla ilgili olarak, WinDbg.exe'ye alternatif olarak adplus.vbs'yi kullanmayı denediniz mi? Çalışan bir işleme eklemek için kullanın

adplus.vbs -crash -p <process_id>

Veya çökmenin hızlı olması durumunda uygulamayı başlatmak için:

adplus.vbs -crash -sc your_app.exe

Adplus.vbs ile ilgili tam bilgi şu adreste bulunabilir: http://support.microsoft.com/kb/286350


1

Hata ayıklayıcı eklenmiş Ntdll.dll

Komut satırı / masaüstünden başlatmak yerine IDE veya WinDbg'den bir program başlatmak arasında çok az bilinen bir fark, eklenmiş bir hata ayıklayıcı ile başlatılırken (yani IDE veya WinDbg) ntdll.dll'nin biraz doğrulama yapan farklı bir yığın uygulaması kullanmasıdır. bellek ayırma / boşaltma konusunda.

Ntdll.dll'de beklenmeyen kullanıcı kesme noktasında bazı ilgili bilgileri okuyabilirsiniz . Sorunu belirlemenize yardımcı olabilecek araçlardan biri PageHeap.exe'dir .

Kilitlenme analizi

Yaşadığınız "çökme" nin ne olduğunu yazmadınız. Program çöktüğünde ve hata bilgilerini Microsoft'a göndermenizi teklif ettiğinde , teknik bilgilere tıklayıp en azından istisna kodunu kontrol edebilmeli ve biraz çaba sarf ederek ölüm sonrası analizi bile gerçekleştirebilmelisiniz ( bkz.Heisenbug : WinApi programı bazı bilgisayarlarda çöküyor) talimatlar için)


1

Vista SP1, sisteme yerleştirilmiş gerçekten güzel bir çökme dökümü oluşturucusuna sahiptir. Ne yazık ki, varsayılan olarak açık değil!

Bu makaleye bakın: http://msdn.microsoft.com/en-us/library/bb787181(VS.85).aspx

Bu yaklaşımın yararı, etkilenen sisteme fazladan bir yazılımın yüklenmesine gerek olmamasıdır. Tut ve yırt, bebeğim!


1

Deneyimlerime göre, bunlar en çok bellek bozulması sorunları.

Örneğin :

char a[8];
memset(&a[0], 0, 16);

: /*use array a doing some thing */

kod çalıştırıldığında hata ayıklama modunda normal olmak çok mümkündür.

Ancak serbest bırakıldığında, bu bir çökme olabilir / olabilir.

Benim için hafızanın sınırlarının dışında olduğu yerleri karıştırmak çok zahmetli.

Görsel Sızıntı Dedektörü (windows) veya valgrind (linux) gibi bazı araçları kullanmak daha akıllıca bir seçimdir .


1

Pek çok doğru cevap gördüm. Ancak bana yardımcı olan kimse yok. Benim durumumda, bir yanlış kullanım vardı SSE talimatları ile unaligned belleğinde . Matematik kitaplığınıza bir göz atın (eğer kullanıyorsanız) ve SIMD desteğini devre dışı bırakmayı, çökmeyi yeniden derlemeyi ve yeniden oluşturmayı deneyin.

Misal:

Bir proje mathfu içerir ve STL vektörü olan sınıfları kullanır: std :: vector <mathfu :: vec2> . STL varsayılan ayırıcısı, gerekli 16 baytlık hizalamayı garanti etmediğinden, bu tür bir kullanım, mathfu :: vec2 öğesinin oluşturulması sırasında büyük olasılıkla bir çökmeye neden olacaktır . Bu durumda fikri ispatlamak için, #define MATHFU_COMPILE_WITHOUT_SIMD_SUPPORT 1her bir mathfu eklemeden önce tanımlanabilir , Release konfigürasyonunda yeniden derlenebilir ve tekrar kontrol edilebilir.

Ayıklama ve RelWithDebInfo yapılandırmaları Projem için iyi çalıştı, ancak Yayın biri. Bu davranışın arkasındaki neden muhtemelen hata ayıklayıcının ayırma / ayırma isteklerini işlemesi ve belleğe erişimleri kontrol etmek ve doğrulamak için bazı bellek defteri tutma işlemleri yapmasıdır.

Durumu Visual Studio 2015 ve 2017 ortamlarında yaşadım.


0

GCC ile bir keresinde bana benzer bir şey oldu. Geliştirme sürecinde değil, yalnızca son sürümü oluştururken etkinleştirilen çok agresif bir optimizasyon olduğu ortaya çıktı.

Doğruyu söylemek gerekirse, kodumun belirli bir optimizasyonun yapılmayacağı gerçeğine dayandığını fark etmediğim için bu gcc'nin değil benim hatamdı.

İzini sürmek çok zamanımı aldı ve ona sadece bir haber grubuna sorduğum için geldim ve biri beni düşündürdü. Öyleyse, bu sana da olursa diye iyiliğimi geri vermeme izin ver.


0

Bu makaleyi senaryonuz için yararlı buldum . ISTR derleyici seçenekleri biraz güncelliğini yitirdi. Yayın derlemeniz için nasıl pdb dosyaları oluşturacağınızı görmek için Visual Studio proje seçeneklerinize bakın.


0

Bunun hata ayıklayıcının dışında ve içinde olmaması şüphelidir; hata ayıklayıcıda çalıştırmak normalde uygulama davranışını değiştirmez. Konsol ve IDE arasındaki ortam farklılıklarını kontrol ederdim. Ayrıca, açık bir şekilde, iyileştirmeler olmadan ve hata ayıklama bilgileriyle yayını derleyin ve bunun davranışı etkileyip etkilemediğini görün. Son olarak, burada başkalarının önerdiği post-mortem hata ayıklama araçlarına bakın, genellikle onlardan biraz ipucu alabilirsiniz.


0

Sürüm yapılarında hata ayıklama, kodunuzun satırlarının çalıştırıldığı sırayı değiştiren optimizasyonlar nedeniyle bir sorun olabilir. Gerçekten kafa karıştırıcı olabilir!

Sorunu en azından daraltmanın bir yolu, kodunuzun programın hangi kısmına sahip olduğunu belirten hızlı ifadeler görüntülemek için MessageBox () kullanmaktır ("Foo ()", "Başlangıç ​​Foo2 ()"); bunları kodunuzun şüphelendiğiniz alanındaki işlevlerin en üstüne yerleştirmeye başlayın (çöktüğü sırada ne yapıyordunuz?). Hangi işlevi anlayabildiğiniz zaman, mesaj kutularını kod bloklarına veya hatta bu işlevin içindeki tek tek satırlara çevirin, ta ki birkaç satıra kadar daraltın. Ardından, çökme noktasında hangi durumda olduklarını görmek için değişkenlerin değerini yazdırmaya başlayabilirsiniz.


Printf'leri serpiştirmeyi çoktan denedi, bu yüzden mesaj kutuları partiye yeni bir şey getirmeyecek.
Greg Whitfield

0

Ayrılan belleğin hangi durumda olduğunu görmek için _CrtCheckMemory () kullanmayı deneyin . Her şey yolunda giderse, _CrtCheckMemory döndüren DOĞRU , başka YANLIŞ .


0

Yazılımınızı Global Flags etkin olarak çalıştırabilirsiniz (Windows için Hata Ayıklama Araçlarına bakın). Çoğu zaman sorunun çözülmesine yardımcı olacaktır.


0

İstisna oluştuğunda programınızın bir mini döküm oluşturmasını sağlayın, ardından bir hata ayıklayıcıda açın (örneğin, WinDbg'de). Bakılacak temel işlevler: MiniDumpWriteDump, SetUnhandledExceptionFilter


0

İşte birinin öğretici bulabileceği bir dava. Yalnızca Qt Creator sürümünde çöktü - hata ayıklamada değil. .İni dosyalarını kullanıyordum (diğer sürücülere kopyalanabilen uygulamaları, Kayıt defteri bozulursa ayarlarını kaybeden uygulamaları tercih ettiğim için). Bu, ayarlarını uygulamaların dizin ağacının altında depolayan tüm uygulamalar için geçerlidir. Hata ayıklama ve yayın yapıları farklı dizinler altındaysa, aralarında da farklı bir ayara sahip olabilirsiniz. Birinde kontrol edilmeyen tercihi kontrol ettirdim. Kazamın kaynağı olduğu ortaya çıktı. İyi ki buldum.

Bunu söylemekten nefret ediyorum, ancak çökmeyi yalnızca MS Visual Studio Community Edition'da teşhis ettim; VS'yi yükledikten sonra, uygulamamın Qt Creator'da çökmesine izin verdim ve onu Visual Studio'nun hata ayıklayıcısında açmayı seçtim . Qt uygulamamın sembol bilgisi olmasa da, Qt kitaplıklarının bazılarına sahip olduğu ortaya çıktı. Beni rahatsız edici çizgiye götürdü; hangi yöntemin çağrıldığını görebildiğim için. (Yine de, Qt'nin kullanışlı, güçlü ve platformlar arası bir LGPL çerçevesi olduğunu düşünüyorum.)


0

Ben de bu problemi yaşadım. Benim durumumda, SERBEST BIRAK modu, linker tanımında msvscrtd.dll'ye sahipti. Onu kaldırdık ve sorun çözüldü.

Alternatif olarak, bağlayıcı komut satırı bağımsız değişkenlerine / NODEFAULTLIB eklenmesi de sorunu çözdü.


-3

Bu hatayı aldım ve vs, temizlemeye çalışırken bile çöktü! Projem. Bu yüzden obj dosyalarını Release dizininden manuel olarak sildim ve bundan sonra gayet iyi oluşturuldu.


-6

Rolf'a katılıyorum. Tekrarlanabilirlik çok önemli olduğu için, hata ayıklama olmayan bir modunuz olmamalıdır. Tüm yapılarınız hata ayıklanabilir olmalıdır. Hata ayıklamak için iki hedefe sahip olmak, hata ayıklama yükünüzü iki katından fazla artırır. Kullanılamaz olmadığı sürece "hata ayıklama modu" sürümünü göndermeniz yeterlidir. Bu durumda onu kullanılabilir hale getirin.


Bu, uygulamaların% 10'u için işe yarayabilir, ancak kesinlikle hepsi için geçerli değildir. DEBUG oluşturulurken yayınlanan oyunları oynamak ister misiniz? Ticari markalı gizli güvenlik kodunuzu demonte dostu modda, hatta PDB'lerle birlikte verin. Sanırım hayır.
steffenj

Steffenj: Oyun geliştiricilerinin hataları bulmasını istiyorum. İdeal olarak, gönderilmeden önce, ama eğer sonraysa, onları yeniden üretmek ve izlemek için yeterli bilgiyi elde edebilmelerini istiyorum. gizli kod ise ticari marka geçerli değildir. PDB'ler? Protein veri bankası mı? python hata ayıklayıcı?
wnoise

IMHO, bu kötü bir fikir. Çalıştırılabilir dosyalar daha büyüktür, optimize edilmemiştir ve çok daha yavaş çalışır. Bu vakalar gerçekten oldukça nadirdir; Olduğunda özellikle sinir bozucu olsa bile. Son derece nadir görülen en kötü durum hata ayıklamasından endişe duyarak sürekli olarak daha düşük kalitede ürünler sunmamalısınız. (Benimki pek çok olumsuz oydan biri değildi.) NASA için bazı programlar yaptım; ve en azından, her kod satırının bir kez test edilmesi gerektiğini söyledik. Birim testi de yardımcı olabilir.
CodeLurker
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.