2016-07-07 18 views
5

Umarım bu soru çok açık uçlu değildir. an "out of memory" from calling next on an Iterator trait object'u bulduğum Rust ile ilgili bir bellek sorunuyla karşılaştım. Hata ayıklama konusunda emin değilim. Baskılar beni sadece hatanın meydana geldiği noktaya getirdi. Ben ltrace gibi diğer araçlara çok aşina değilim, bu yüzden bir iz oluşturabilirim (231MiB, pff), gerçekten onunla ne yapacağımı bilmiyordum. Böyle bir iz yararlı mı? Gdb/lldb'yi ele geçirmek için daha iyisini yapar mıyım? Ya da Valgrind?Rust'taki bir bellek sorununu nasıl ayırım?

+0

Valgrind her zaman iyi bir başlangıçtır. Kodunuzu da optimize etmeyi deneyin. –

+2

@EliSadoff Kodumu optimize etmek, hata ayıklama sorunları ile nasıl yardımcı olur? – Apanatshka

cevap

3

Genelde ben aşağıdaki yaklaşımı yapmaya çalışacağını söyledi:

  1. Demirbaş azalma: etrafta çok fazla ek kod yok ki, OOM sorununu daraltmak için deneyin. Diğer bir deyişle: programınız ne kadar hızlı çöker, o kadar iyidir. Bazen, belirli bir kod parçasını parçalamak ve soruşturma için ekstra bir ikili haline getirmek de mümkündür.

  2. Sorun boyut küçültme: Alt aslında bir OOM neden olmadığını ancak bazı parça atıklar şey söyleyebilirim ki basit bir "çok fazla belleğe" için OOM gelen sorunu. Sorunu görüp görmediğinizi anlamak çok zorsa, bellek sınırını düşürebilirsiniz. Linux'ta bu ulimit kullanılarak yapılabilir:

    ulimit -Sv 500000 # that's 500MB 
    ./path/to/exe --foo 
    
  3. Bilgi toplama: Sorunun kadar küçük, bir düşük ses seviyesine bilgi toplamak için hazır. Denemeniz için birçok yol var. Sadece programınızı debug sembolleri ile derlemeyi unutmayın. Ayrıca, genellikle bilgi kaybına yol açtığı için optimizasyonu kapatmak bir avantaj olabilir. Her ikisi de derleme sırasında --release bayrağını kullanarak DEĞİL tarafından arşivlenebilir.

    • Öbek profilleme: Tek yol çok gperftools kullanmak edilir:

      LD_PRELOAD="/usr/lib/libtcmalloc.so" HEAPPROFILE=/tmp/profile ./path/to/exe --foo 
      pprof --gv ./path/to/exe /tmp/profile/profile.0100.heap 
      

      Bu size programın parçaları bellek hangi miktarda yemek hangi simgeleyen grafiğini gösterir. Daha fazla bilgi için official docs'a bakın.

    • rr: Bazen, özellikle bir profil oluşturulduktan sonra gerçekte ne olduğunu anlamak çok zor. 2. adımda iyi bir iş yaptı varsayarsak, rr kullanabilirsiniz:

      rr record ./path/to/exe --foo 
      rr replay 
      

      Bu süper güçleri olan bir GDB doğacaktır. Normal bir hata ayıklama oturumu arasındaki fark, yalnızca continue değil, aynı zamanda reverse-continue. Temel olarak programınız istediğiniz gibi ileri geri atlayabileceğiniz bir kayıttan yürütülür. This wiki page bazı ek örnekler sağlar. Dikkat edilmesi gereken bir nokta, rr'nin sadece GDB ile çalıştığı görülmektedir.

    • Eski iyi hata ayıklama: Bazen, hala çok büyük izler ve kayıtlar alırsınız. Bu durumda (ulimit hile ile birlikte) sadece programı çöker kadar GDB kullanabilir ve bekleyebilir:

      gdb --args ./path/to/exe --foo 
      

      Bu sayede, program mevcut durumu ne inceleyebilirsiniz normal hata ayıklama oturumu almalısınız . GDB aynı zamanda coredumps ile de piyasaya sürülebilir. Bu yaklaşımla ilgili genel sorun, zamanda geriye gidemeyeceğiniz ve yürütmeye devam edemeyeceğiniz yönündedir. Böylece sadece tüm yığın çerçeveleri ve değişkenleri içeren mevcut durumu görüyorsunuz. İsterseniz LLDB'yi de kullanabilirsiniz.

  4. (Potansiyel) + tekrarı düzeltmek: size kodunu değiştirmek için deneyebileceğiniz yanlış gidebileceğini ne tutkal sonra. Sonra tekrar dene. Hala çalışmıyorsa, 3. adıma dönün ve tekrar deneyin.

1

Genelde, hata ayıklamak için, günlük tabanlı bir yaklaşım kullanabilirsiniz (günlükleri kendiniz ekleyerek veya ltrace, ptrace, ... sizin için günlükleri oluşturmak için). Bir hata ayıklayıcı kullanın.

Not: ltrace, ptrace veya hata ayıklayıcı tabanlı yaklaşımlar, sorunu yeniden oluşturabilmenizi gerektirir; Manuel günlükleri destekleme eğilimindeyim çünkü hata raporlarının hemen yeniden üretime izin vermeyecek kadar kesin olmadığı bir endüstride çalışıyorum (ve böylece yeniden üreteci senaryosunu oluşturmak için günlükleri kullanıyoruz).

Pas her iki yaklaşımı destekler ve C veya C++ programları için kullanılan standart araç takımı bunun için iyi çalışır.

Kişisel yaklaşımım, sorunun oluştuğu yerlerin hızlı bir şekilde daraltılması için numaralı oturumunun günlüğe kaydedilmesi ve günlüğe kaydetmenin, daha ince bir denetim için bir hata ayıklayıcısını tetiklemek için yetersiz kalmasıdır. Bu durumda hata ayıklayıcısına hemen gitmenizi öneriyorum.

panic A, bir panik kancasına yapılan çağrıyı keserek, işlerin kötüye gittiği anda hem çağrı yığınını hem de bellek durumunu görebildiğiniz anlamına gelir.

Programınızı hata ayıklayıcınızla başlatın, panik kancada bir kesme noktası ayarlayın, programı çalıştırın, kar edin.

İlgili konular