2012-08-02 17 views
5

Bir minidump'a göre, bazı dosyalar özyinelemeli bir ayrıştırıcıda yığın taşmasına neden olan bir durumla karşılaştım. Maalesef ellerimi, sorunu çözmek için bunu yapan bir dosya örneğini alamıyorum (müşterinin gizlilik endişeleri var), ki bu, şu andaki gerçek problemin teşhisi için beni biraz sinirlendiriyor.Bir çalışan iş parçacığındaki yığın taşmasını nasıl önleyebilirim veya kurtarırım?

Çözümleyicinin biraz dikkat etmesi gerekiyor, ancak şu an için en öncelikli programın çalışmaya devam etmesini sağlamaktır. Bir stopgap önlemi olarak, tüm programı indirmekten kaçınmak için ne yapabilirim?

Benim ilk tercihi taşma olmadan önce ben incelikle ayrıştırıcı iptal böylece ben yığın odasına tükeniyor tahmin etmenin bir yolunu bulmak olacaktır. Dosya ayrıştırılamıyor kabul edilebilir bir seçenektir. İkinci seçenek, bunun olmasına izin vermek, hatayı yakalamak ve kayıt etmek, ardından verilerin geri kalanıyla devam etmek olacaktır.

ayrıştırma bir Parallel.ForEach() döngü içinde gerçekleşiyor. Bu yardımcı olacak başka bir yaklaşım için bunu değiştirmek için istekli değilim.

DÜZENLEME: Geçerli katmanın yığınının boyutunu ve yığın işaretçisinin konumunu alabilseydim gerçekten katil ne olurdu? Mümkün mü?

DÜZENLEME 2: Sonunda bir örnek dosyasını birinden çıkarmayı başardım ve hatayı bir hata ayıklayıcısında yakaladım. Bu, bize ait olan kod değil - istisna HtmlAgilityPack'da bir yerde oluyor. Öyle görünüyor ki, tamamen farklı bir tack bulmaya çalışacağım.

+0

Yığın taşmasına tam olarak neden olan şey net olmadığından (paralellizm bu duruma neden olmamalıdır: recursiveness olabilir) yardımcı olacağından emin değilsiniz, ancak aynı anda yapılan aramaların miktarını sınırlamak için 'ParallelOptions.MaxDegreeOfParallelism' kullanmayı denediniz mi? – Jcl

+0

Bir seçenek sadece parse geçerli "derinlik" izlemek ve çok yüksek alırsa kefalet etmektir. – dlev

+0

@dlev Yine de daha fazla ayrıntı istiyorum. .NET belgelerine göre, hem yığın çerçeveleri hem de çağrı yığını bir bütün olarak farklı boyutlara sahip olabileceğinden, uygun bir maksimum derinliği nasıl seçerim? –

cevap

3

Yığın, masaüstü CLR'de varsayılan olarak 1 MB sınırına sahip, ancak siz can increase it.

Sen yığını yerine yığın kullanmak için bir continuation passing style kullanabilirsiniz.

C# 5.0'da, bu işlemi otomatikleştiren derleyici tarafından sağlanan bir uyumsuzluk mekanizması vardır. Bunu en son yapıyla denemedim. Alex'in belirttiği gibi, C# 'da kuyruk arama optimizasyonu için bir destek yoktur ve bu, ayrıştırma problemleri için F #' yı kullanmanın bir sebebi olabilir. Ayrıca presence of bad inputs daki programı katı hale getirmek için grafik çevrim algılama gerekiyordu this article.

gösterildiği gibi Burada, some material on lexing and parsing with F#. YMMV bu.

Daha fazla bilgi toplamanın bir yolu olarak, çağrı yığınının ne kadar derin olduğunu izleyen bir akümülatör tamsayısına iğne yapabilirsiniz. Bu, doğrudan bahsedilen çağrı yığını tarafından tüketilen belleğe dönüştürülmez, ancak size genel bir fikir verir. Örneğin, bu sayı, kullanıcı tarafından yapılandırılabilen veya önceden tanımlanmış bir eşikten daha büyük olduğunda, kendi özel durumunuzu atabilir ve yakalayabilirsiniz.

public void Recursive(int acc) 
{ 
    if (acc > myLimit) 
     throw new MyOverflowException(acc); 

    Recursive(acc+1); 
} 

ve sonra çağrı yerinde: istenen gibi

try { Recursive(0); } catch (MyOverflowException) { /* handle it*/ } 

, ben nedeniyle KİT çökmesini this very topic.

+1

Biraz ayrıntı güzel olurdu. –

+0

@GregC Bu, uzun vadeli bir çözüm olarak düşünmeyi düşündüğüm bir şey. Ama şu anda bir stopgap arıyorum ve bu oldukça büyük bir refactor olacaktır. –

+1

Devam eden bir geçiş stili örneği vermek istiyorum ve belki de bunun daha az yığını nasıl kullandığını gösterebilir. –

0

bir iş parçacığı üzerinde Eric Lippert tarafından muhteşem bloga seni bağlarız tüm süreci indirecek ve bunun hakkında yapabileceğiniz fazla bir şey yok.Bir kurtarma önlemi olarak, ayrıştırıcıyı ayrı bir işlem olarak başlatabilir ve çocukla iletişim kurmak için bir IPC mekanizması kurabilirdiniz. Bu şekilde, çocuk süreci ana süreci etkilemeden ölmek için özgürdür.

İlgili konular