Neden özyinelemeli çağrı neden farklı StackOverflow derinliklerinde yığını mı?
Kuyruk çağrılarını C ile nasıl işleneceğini uygulamalı anlamaya çalışıyordum# derleyici.
(Cevap: They're not. Ama64 bit JİT(ler)OLACAK TCE (kuyruk Ara eleme). Restrictions apply.)
Küçük bir test StackOverflowException
süreç öldürmeden önce aradı ne kadar yazdıran bir özyinelemeli arama kullanarak yazdım.
class Program
{
static void Main(string[] args)
{
Rec();
}
static int sz = 0;
static Random r = new Random();
static void Rec()
{
sz ;
//uncomment for faster, more imprecise runs
//if (sz % 100 == 0)
{
//some code to keep this method from being inlined
var zz = r.Next();
Console.Write("{0} Random: {1}\r", sz, zz);
}
//uncommenting this stops TCE from happening
//else
//{
// Console.Write("{0}\r", sz);
//}
Rec();
}
Tam vaktinde, program: BÖYLECE İstisna ile sona erer
- 'Optimize' (hata Ayıklama veya Sürüm) . inşa
- Hedef: 86
- Hedef: "" (bu VS 2012 ve ilk defa gördüm. yeni 32 bit Tercih AnyCPU More here.)
- Zararsız görünen bazı kod (bkz. 'başka' şube). açıklamalı şube
Tersine, 'kullanarak Optimize inşa' (Hedef = 64 veya AnyCPU 'Tercih 32' (OFF bir 64-bit CPU)), TCE olur ve sayaç dönmeye devam ediyor. sonsuza kadar (Tamam, belki döneraşağıkendi değer taşıyor her zaman).
Ama açıklayamadığım bir davranış olduğunu fark ettimStackOverflowException
Bu durumda: hiç (?) olurtam olarakaynı yığın derinliği. Burada bir kaç 32-bit çalışır, Yayın oluşturma: çıktılar
51600 Random: 1778264579
Process is terminated due to StackOverflowException.
51599 Random: 1515673450
Process is terminated due to StackOverflowException.
51602 Random: 1567871768
Process is terminated due to StackOverflowException.
51535 Random: 2760045665
Process is terminated due to StackOverflowException.
Ve hata Ayıklama yapı:
28641 Random: 4435795885
Process is terminated due to StackOverflowException.
28641 Random: 4873901326 //never say never
Process is terminated due to StackOverflowException.
28623 Random: 7255802746
Process is terminated due to StackOverflowException.
28669 Random: 1613806023
Process is terminated due to StackOverflowException.
Yığın boyutu sabittir (**15). Çerçeve boyutları sabittir. yığını
O zaman, (bazen önemsiz) için hesap StackOverflowException
çarptığında varyasyon adımı ne olabilir?
GÜNCELLEME
Hans geçerken Alma Console.WriteLine
konusu, P/Çağır, birlikte çalışma dokunaklı ve muhtemelen belirli olmayan kilitleme yükseltir.
Bu kodu basit:
class Program
{
static void Main(string[] args)
{
Rec();
}
static int sz = 0;
static void Rec()
{
sz ;
Rec();
}
}
Sürüm/32 bit/Optimizasyon bir hata ayıklayıcı olmadan koştum. Program çöküyor, hata ayıklayıcı ve sayaç değerini kontrol edin.
Ve buhalaaynı birkaç çalışır değil. (Ya da benim test hatalı.)
GÜNCELLEME: Kapanış
Fejesjoco önerdiği gibi, ASLR (Adres alanı düzeni rasgele) içine baktım.
Bu bir güvenlik tekniği zorlaştırıyor arabellek taşması saldırıları bulmak için hassas konum (örneğin) belirli sistem çağrıları tarafından rastgele çeşitli şeyler, işlem adres alanı dahil olmak üzere bir yığın pozisyon ve, görünüşe göre, onun büyüklüğü.
Teoride kulağa hoş geliyor. Bu uygulamaya koyalım!
Bu test etmek için, Microsoft aracı belirli bir görev için kullandım: EMET or The Enhanced Mitigation Experience Toolkit. Sistem veya İşlem düzeyinde bir ASLR bayrağı (ve çok) daha fazla ayar sağlar.
(Denemedim de system-wide, registry hacking alternative var)
Aracı etkinliğini doğrulamak için, ben de Process Explorer özel olarak ASLR bayrağı durumunu bildirir keşfetti 'Özellikler' sürecinin sayfası. Hiç görmedim bugün :) o kadar
Teorik olarak, EMET (re)tek bir işlem için ASLR bayrağı ayarlayabilirsiniz. Pratikte, bir şey (bkz: yukarıdaki resim) değiştirmek için görünmüyordu.
Ancak, ASLR, tüm sistem için devre dışı bıraktım ve bir yeniden başlatma sonra) sonunda gerçekten doğrulayın. o YÜZDEN ben de bu durum artık her adımı aynı anda olur.
BONUS
ASLR ile ilgili eski haberler: How Chrome got pwned
CEVAP
İş yerinde ASLR olabilir bence. DEP bu teoriyi test etmek için devre dışı bırakabilirsiniz.
"C" için buraya bakın# programı sınıfı hafıza bilgilerini kontrol etmek için: http://stackoverflow.com/a/8716410/552139
Bu araç ile, yarım sayfa olan en küçük ve en büyük yığın boyutu arasındaki fark yaklaşık 2 KiB olduğunu buldum. Bu çok garip.
Güncelleme: TAMAM, şimdi haklı olduğumu biliyorum. Yarım sayfalık teoriyi takip ettim ve Windows ASLR uygulanmasını inceleyen bu doktor bulundu: http://www.symantec.com/avcenter/reference/Address_Space_Layout_Randomization.pdf
Alıntı:
Yığın, ilk daha işaretçi yığını konulmuş bir kez rastgele ters ilişkiye miktarda bulunmaktaydı. İlk dengeleniyor seçili yarım sayfa kadar (2048 bayt)
Ve bu sorunun cevabı. ASLR ilk 0 arasında ve 2048 bayt rasgele yığını alır.
Neden özyinelemeli yapıcı bir çağrı ge...
Neden Windows64 86-64 diğer tüm İşleti...
C ve C her ikisi içinde geçerli bir ko...
Neden Python karşılaştırma dizeleri ku...
Neden toplam sırasını değiştirerek far...