Win32 altında yığın bozulması; nasıl bulmak için?

oy
54

Ben üzerinde çalışıyorum parçacıklı yığın bozulmasını C ++ uygulaması. Bu yolsuzluk bulmak için olağan araçlar uygulanamaz olduğu görülüyor. Eski kaynak kodu sergi En son sürümü ile aynı davranış (18 aylık) oluşturur ve bu nedenle bu uzun bir süre için yaklaşık edilmiş ve sadece fark değildi; olumsuz, kaynak deltaları böcek tanıştığında tanımlamak için kullanılamaz - vardır bir sürü veri havuzundaki kod değişiklikleri.

bir iç gösterimine munged verilerin yuva transferi - behaviuor çökmesini istemi bu sistemde verim elde etmektir. (-: yığın bozulması dolayısıyla yığın alloc başarısız dahil olmak üzere çeşitli yerlerde, çeşitli nedenler) Ben periyodik istisna uygulaması neden olacaktır Test verilerinin bir dizi var.

davranış işlemci gücü veya bellek bant genişliği bağlı gözükmektedir; Makinenin sahip olan her fazlasını, daha kolay kilitlenmesine etmektir. Bir hiper-diş çekirdek veya bir çift çekirdekli çekirdek devre dışı bırakılması bozulmasını hızını azaltan (ortadan değildir). Bu bir zamanlama ile ilgili sorunu göstermektedir.

Şimdi burada ovmak:
o hafif ayıklama ortamında çalışacak zamanlarda (diyelim Visual Studio 98 / AKA MSVC6) yığın bozulması çoğaltmak oldukça kolaydır - on ya da on beş dakika geçmesi şey bir benzeri, horrendously ve istisnalar bozulmadan önce alloc;(Akılcı Arındırmak sofistike ayıklama ortamında çalışırken, VS2008/MSVC9işlemci yukarıda almıyor: hatta Microsoft Application Doğrulayıcı) sistem belleği hızlı bağlı olur ve hafıza bağlı (çökmez 50%kutu tüketen, disk ışığı değil, programın kadar hızlı bir gidiyor 1.3G) RAM 2G . Yani, ben sorunu yeniden (ama nedenini belirlemek değil) edememek veya nedenini veya ben yeniden olamaz bir sorun belirlemeleri edememek arasında bir seçim var.

yanında nereye doğru Benim şu anki en iyi tahmin:

  1. (Güncel geliştirme kutusu yerine: Bir 2 GB RAM delicesine Grunty kutusu alın E6550 Core2 Duo); Bu mümkün güçlü hata ayıklama ortamında çalışırken yanlış davranışa neden kazasında üreme için yapacak; veya
  2. Operatörlerini yeniden yazın newve deletekullanımı VirtualAllocve VirtualProtectsalt okunur en kısa sürede onunla bitti olarak hafızayı işaretlemek için. Altında çalıştırın MSVC6ve OS serbest belleğe yazıyor kötü adamı yakalamak var. Cehennem yeniden yazar: Evet, bu çaresizlik göstergesidir newve delete?! Bu Purify vd altında olduğunca yavaş yapacak merak ediyorum.

Ve hiçbir: yerleşik Arındırmak enstrümantasyon ile Kargo bir seçenek değildir.

Bir meslektaşım sadece geçmiş yürüdü ve sordu Yığın taşması? Biz yığını alıyorsunuz şimdi taşıyor?!?

Ve şimdi, soru: Nasıl yığın Corruptor bulabilirim?


Güncelleme: dengeleme new[]ve delete[]problem çözme yolunda uzun bir yol aldık görünüyor. Bunun yerine 15mins, uygulamanın şimdi çarpmadan önce yaklaşık iki saat gider. Orada henüz. Herhangi başka bir öneriniz? Yığın bozulması devam etmektedir.

Güncelleme: Visual Studio 2008 altında Sürüm oluşturma dramatik iyi görünüyor; Geçerli şüphe üzerinde durur STLuygulaması ile gemi VS98.


  1. Sorunu Yeniden. Dr WatsonDaha fazla analiz yardımcı olabilecek bir dökümü üretecek.

Ben bunu not alacağım ama Dr Watson sadece yığın çiğnendi oluyor değilken, aslında sonra takıldı olacak endişeleniyorum.

Başka deneyin kullanıyor olabilir WinDebugaynı zamanda anda hafif olmak oldukça güçlüdür Hata ayıklama aracı olarak.

pek yardım şey yanlış giderse kadar: Tekrar şu anda gidiş olduğunu var. Ben eyleminde kundaklayanı yakalamak istiyorum.

Belki bu araçlar en az belirli bileşene sorunu daraltmak için izin verecektir.

Ben çok umut tutmayın ama umutsuz zamanlar için çağrı ...

Ve projenin tüm bileşenleri (doğru çalışma zamanı kitaplığı ayarlarına sahip eminiz C/C++ tabVS 6.0 proje ayarlarında, Kod Üretimi kategori)?

Hayır, değilim, ben (o 58 proje) çalışma alanı geçmekte ve hepsi derleme ve uygun bayraklarıyla bağlıyoruz denetleme yarın birkaç saat harcarsınız.


Güncelleme: Bu 30 saniye sürdü. Tüm projeleri seçin SettingsEğer doğru ayarları (hepsi doğru ayarları vardı) yok projesini (ler) bulana kadar diyalog, işaretini kaldırın.

Oluştur 04/08/2008 saat 08:30
kaynak kullanıcı
Diğer dillerde...                            


15 cevaplar

oy
26

Benim ilk tercihi gibi özel bir yığın aracı olacağını Pageheap.exe .

Yeni Yeniden Yazma ve silme faydalı olabilir, ama bu alt düzey koduna göre işlenen ayırmalar yakalamak etmez. İstediğin bu ise, daha iyi Detour için low-level alloc APIMicrosoft Detours kullanarak s.

gibi Ayrıca aklı denetler: kötü siler arayın ve daha sonra çalışma zamanı kütüphaneleri maçı doğrulamak (ayıklama, çok kanallı vs statik lib tek iş parçacıklı, dll vs vs serbest bırakılması) (örneğin [] nerede olmalıydı delete ) kullanılan, sen karıştırma ve ayırmalar uymayan emin olun.

Ayrıca seçici konuları kapatarak ve problem ortadan kalkıp kalkmadığını zaman görmek / deneyin.

vb çağrı yığını ilk istisna sırasında neye benziyor?

Cevap 04/08/2008 saat 08:51
kaynak kullanıcı

oy
11

İşimde aynı sorunlarla (biz de kullanmak VC6bazen). Ve bunun için hiç de kolay bir çözüm yoktur. Sadece bazı ipuçları vardır:

  • (Bkz otomatik kazasıyla üretim makinesinde döker deneyin Süreç Damper ). Benim deneyim Watson diyor mükemmel değil damping için.
  • Tümünü kaldır catch (...) kodunuzdan. Bunlar genellikle ciddi bellek istisnalar gizlemek.
  • Kontrol Advanced Windows Debugging - sizinki gibi sorunları için büyük ipuçları bir sürü vardır. Ben bütün kalbimle tavsiye bu.
  • Eğer kullanırsanız STLdenemek STLPortve kontrol oluşturur. Geçersiz yineleme cehennem vardır.

İyi şanslar. Sizinki gibi sorunlar çözmek için ayımızı alır. Bunun için hazır olun ...

Cevap 06/08/2008 saat 13:41
kaynak kullanıcı

oy
8

Orijinal uygulamayı çalıştırın ADplus -crash -pn appnename.exe hafıza sorunu çıkana-up Ne zaman güzel bir kocaman boşaltmış alacak.

Sen bozuk ne hafıza konumu anlamaya dökümü analiz edebilirsiniz. Eğer şanslıysanız üzerine yazma bellek o nereden geldiğini anlamaya benzersiz bir dizedir. Eğer şanslı iseniz, içine kazmak gerekir win32yığın ve orignal bellek özelliklerinin ne olduğunu anlamaya. (yardımcı olabilecek -x yığın)

Eğer ne haberci-up biliyorum sonra, özel yığın ayarlarıyla kullanımını AppVerifier daraltabilirsiniz. yani ne belirtebilirsiniz DLLizlemek, ya da ne ayırma boyutu izlemek için.

Umarım bu suçlu yakalamak için yeterli izleme hızlandıracaktır.

Benim durumumda, ben tam yığın doğrulayıcı modunu ihtiyacım olmadı, ama kilitlenme dökümü (ler) ve tarama kaynaklarının analiz çok zaman geçirdi.

Not: Sen kullanabilirsiniz DebugDiag döker analiz etmek. Bu işaret edebilir DLLsahibi bozuk yığın ve size diğer yararlı bilgi vermek.

Cevap 16/09/2008 saat 08:33
kaynak kullanıcı

oy
7

Biz kendi malloc ve ücretsiz fonksiyonlarını yazarak oldukça iyi şans oldu. üretimde, sadece standart malloc ve ücretsiz çağrı, ancak hata ayıklama, onlar ne istersen yapabilirsin. Biz de hiçbir şey yapmaz basit bir temel sınıf var ancak yeni geçersiz kılmak ve bu işlevleri kullanmak operatörleri silmek, o zaman yazma herhangi sınıfı sadece o sınıftan devralabilir. Eğer kod bir ton varsa, yeni malloc ve (realloc unutmayın!) ücretsiz malloc ve ücretsiz çağrı yerine büyük bir iş olabilir, ama uzun vadede çok yararlı olur.

Steve Maguire kitabında Katı Kod Yazma (tavsiye), sen gibi bu rutinleri içinde yapabileceği ayıklama şeyler örnekleri vardır:

  • sızıntıları bulmak için ayırmaları takip edin
  • gerektiğinden fazla bellek ve başında ve bellek sonunda işaretleri koymak - bedava rutini sırasında, bu belirteçler hala orada sağlayabilirsiniz
  • tahsisi bir işaretleyici ile hafıza memset'in ve ücretsiz (başlatılmamış bellek kullanımını göstermek için) (free'd bellek kullanımını göstermek için)

Başka iyi bir fikir olduğunu asla gibi şeyler kullanmak strcpy, strcatya da sprintf- her zaman kullanmak strncpy, strncatve snprintf. Biz bir tampon sonunu kapalı yazmayın emin olmak için, hem de bunların kendi versiyonlarını yazdım ve bu da çok problem yakaladık.

Cevap 22/08/2008 saat 18:11
kaynak kullanıcı

oy
4

Sen zamanında ve statik analizi hem bu sorunu saldırmak gerekir.

Statik analiz için PREfast ile derleme düşünün ( cl.exe /analyze). Bu uyumsuz algılar deleteve delete[]tampon taşması ve diğer sorunları bir dizi. Hazırlıklı olun, yine de, proje hala gelmiştir, özellikle L6 uyarı birçok kilobayt ile Wade L4sabit değildir.

PREfast, Visual Studio Team System ile mevcuttur ve görünüşe Windows SDK bir parçası olarak,.

Cevap 12/10/2008 saat 22:55
kaynak kullanıcı

oy
3

Bu düşük bellek koşullarında mı? Yeni dönen olduğunu olabilir Eğer öyleyse NULLstd :: bad_alloc atma yerine. Yaşlı VC++derleyiciler düzgün bu uygulamaya vermedi. Hakkında bir makale vardır Legacy bellek ayırma başarısızlıkları çökmesini STLile inşa uygulamaları VC6.

Cevap 02/09/2008 saat 07:03
kaynak kullanıcı

oy
3

bellek bozulması nedeniyle belirgin Rastgeleliğin parçacığı eşitleme sorun gibi çok geliyor - bir hata makinesi hızına bağlı olarak yeniden üretilir. nesneler (hafızanın chuncks) parçacıkları ve senkronizasyon arasında paylaşılıyorsa (kritik bölümünde, muteks, semafor, diğer) ilkel başına sınıfı (nesne başına, her bir sınıf) temelinde, o zaman bir duruma gelmek mümkündür bulunmayan sınıf (bellek öbek) silinir burada / kullanım sırasında serbest veya silinmiş / sonra serbest kullanılır.

Bunun için bir test olarak, her sınıf ve yönteme senkronizasyon ilkeller ekleyebilir. Birçok nesneleri birbirleri için beklemek zorunda kalacak çünkü bu kod yavaş yapacaktır, ancak bu yığın hatalarını ortadan kaldıran bile, yığın yolsuzluk sorunu bir kod optimizasyonu biri olacak.

Cevap 25/08/2008 saat 20:55
kaynak kullanıcı

oy
1

Silmek / yeni yeniden seçerseniz, bunu bitirmeye ve basit kaynak kodunu de var adres:

http://gandolf.homelinux.org/~smhanov/blog/?id=10

Bu bellek sızıntıları yakalar ve ayrıca yığın bozulmasına yakalamak için önce ve bellek bloğu sonra koruma verileri ekler. Sadece her CPP dosyasının en üstünde #include "Debug.h'ye" koyarak ve DEBUG ve DEBUG_MEM tanımlayarak onunla entegre edebilirsiniz.

Cevap 17/09/2008 saat 14:40
kaynak kullanıcı

oy
1

Sahip olduğunuz sınırlı bilgi elde Yani, bu bir veya daha fazla şeylerin bir kombinasyonu olabilir:

  • Kötü yığın kullanımı, yani ücretsiz sonra okunan çift boşaltır, ayırmalar ile HEAP_NO_SERIALIZE bayrağı ayarlayarak, ücretsiz sonra yazmak ve aynı öbek üzerinde birden çok iş parçacığı boşaltır
  • Bellek yetersiz
  • Kötü kodunu (yani tampon taşması, tampon underflows, vs.)
  • "Zamanlama" konular

en buysa tüm ilk iki ama geçen değil, ya Pageheap.exe ile şimdiye kadar bunu yakalanmış olması gerekirdi.

Hangi büyük olasılıkla o kod paylaşımlı bellek erişen nasıl kaynaklanmaktadır gelir. Ne yazık ki, aşağı izleme oldukça sancılı olacak. Paylaşılan belleğe Eşitlenmemiş erişim genellikle tuhaf "zamanlama" konuları belli eder. vb uygun kilitleri kullanmayan bir bayrak ile paylaşılan bellek erişimi senkronize etmek için acquire / bırakma sözcüklerle değil gibi şeyler

En azından, daha önce belirtilmiş olduğu gibi, her nasılsa ayırmalarını izlemek edebilmek için yardımcı olacaktır. En azından o aslında yığın bozulması kadar olanları görmek ve bundan teşhis etmeyi deneyebilir.

Kolayca birden yığınları için tahsisleri yönlendirebilirsiniz Ayrıca, eğer sen o sorunu veya daha fazla reproduceable arabası davranış sonuçları giderir ya olmadığını görmek için denemek isteyebilirsiniz.

Eğer VS2008 ile test edildiğinde Konserve Hafıza Evet olarak ayarlayın, sen HeapVerifier ile kaçtın? Bu yığın ayırıcı performans etkisini azaltmak olabilir. (Dahası, bunun Debug-> Uygulama doğrulayıcısı'nın ile başlayın çalıştırmak zorunda, ama bunu zaten biliyor olabilir.)

Ayrıca WinDbg ve! Yığın komutunun değişik kullanımları ile ayıklama deneyebilirsiniz.

MSN

Cevap 22/08/2008 saat 17:51
kaynak kullanıcı

oy
0

Birkaç öneri. Sen W4 de bol uyarıları söz - Ben uyarı 4 seviyesinde temiz derlemek için kodunuzu düzeltmek için zaman ayırdığınız öneririz - Bu hataları bulmak zor ince önlenmesi için uzun bir yol gidecek.

İkincisi - için / anahtarını analiz - gerçekten bol uyarıları nasıl üretir. Kendi projede bu anahtarı kullanmak için Yaptığımın analiz / tarafından oluşturulan tüm ek uyarıları kapatmak için # Pragma uyarı kullanılan yeni bir başlık dosyası yaratmaktı. Sonra daha da aşağı dosyada, ben umurumda sadece bu uyarıları açın. Sonra İlk olarak tüm derleme birimlerine dahil edilecek bu başlık dosyasını zorlamak için / FI derleyici anahtarını kullanın. çıktıyı denetimden ederken bu kullanmayı / anahtarı analiz izin vermelidir

Cevap 03/10/2009 saat 17:48
kaynak kullanıcı

oy
0

Bunun bir yarış durumu olduğunu düşünüyor musunuz? Birden çok iş parçacığı bir yığın paylaşıyorsunuz? Her konuyu HeapCreate ile özel bir yığın verebilir, o zaman HEAP_NO_SERIALIZE ile hızlı koşabilir. Eğer sistem kütüphanelerinin çok kanallı sürümünü kullanıyorsanız Aksi takdirde, bir yığın, güvenli iş parçacığı edilmelidir.

Cevap 30/07/2009 saat 14:48
kaynak kullanıcı

oy
0

Ben az zaman benzer bir sorunu çözmek için. Sorun hala devam ediyorsa ben bunu önermek: yeniye tüm çağrıları Monitör / silme ve malloc / calloc / realloc / ücretsiz. Ben kasa için tüm çağrıları bir işlev ihraç tek bir DLL olun. Bu fonksiyon tahsis alanı ve bir masa bu bilgileri kaydetme çağrının tipine kodunuzu kaynağı, işaretçi tanımlamak için parametre alırlar. Tüm tahsis / serbest çifti elimine edilir. Sonunda ya sonra sol veri için rapor oluşturmak için bir başka işleve bir çağrı yapmak gerekir. Bununla yanlış çağrıları (yeni / ücretsiz ya da malloc / silme) ya da eksik tespit edebilir. Kodunuzdaki üzerine tampon herhangi kılıf varsa kaydedilen bilgiler yanlış olabilir ama / algılayabilir her test / keşfetmek tespit başarısızlık bir çözüm bulunur. Birçok çalışır hataları tespit yardımcı olur. İyi şanslar.

Cevap 19/12/2008 saat 12:52
kaynak kullanıcı

oy
0

ücretsiz özel malloc / ait Graeme önerisi iyi bir fikirdir. size kaldıraç için bir tanıtıcı vermek yolsuzlukla ilgili bazı desen karakterize miyiz.

Aynı boyutta bir blok içinde her zaman Örneğin, (64 bayt diyelim) daha sonra her zaman kendi sayfasında 64 bayt parçalarını ayırmak için malloc / ücretsiz çifti değiştirin. Eğer 64 byte yığın sonra önlemek için bu sayfadaki bellek koruma bitleri set özgür bıraktığında okur ve wites (VirtualQuery kullanarak). Sonra bu hafızayı erişmeye çalışan herkes yığın bozulmasını yerine bir istisna oluşturur.

Bu seçkin 64 byte parçaları sayısı sadece ılımlı ya da kutuya yakmak için çok fazla bellek olduğunu varsayalım yok!

Cevap 02/09/2008 saat 05:23
kaynak kullanıcı

oy
0

aşağıdaki gibi Benim ilk eylemi olacaktır:

  1. "Yayın" sürümü ama hata ayıklama bilgisi dosyası oluşturma konusunda ikilileri kurmak (proje ayarlarında bu imkanı bulacaksınız).
  2. Eğer sorunu yeniden istediğiniz bir makinede bir Varsylan ayıklayıcıya (DrWtsn32 -I) olarak Dr. Watson kullanın.
  3. Sorunu Repdroduce. Dr Watson fazla analiz yardımcı olabilecek bir dökümü üretecek.

Başka deneyin aynı zamanda anda hafif olmak oldukça güçlüdür Hata ayıklama aracı olarak WinDebug kullanıyor olabilir.

Belki bu araçlar en az belirli bileşene sorunu daraltmak için izin verecektir.

Ve projenin tüm bileşenleri (VS 6.0 proje ayarları C / C ++ sekmesi, Kod Üretimi kategori) doğru çalışma zamanı kitaplığı ayarlarına sahip olduğundan emin misin?

Cevap 04/08/2008 saat 09:26
kaynak kullanıcı

oy
0

Eski inşa çalıştı ama sen daha geriye depo tarihinin gidiş ve hata tanıtıldı tam olarak ne zaman görmeye devam edemez bir sebebi var mı?

Aksi takdirde, ben özel olarak giriş yapmak isteyebileceğiniz bir kayıp am rağmen, sorunu saptamak yardımcı olacak bazı tür basit günlüğü ekleyerek öneririz.

tam olarak google ve alıyorsanız istisnalar belgelerine aracılığıyla, bu soruna yol CAN öğrenebilirsiniz, belki o kodda bakmak için ne daha fazla fikir verecektir.

Cevap 04/08/2008 saat 08:48
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more