2015-02-17 31 views
7

Java kişisi burada biraz C++ yapıyor. Bir istisna yakalıyorum ve nereden geldiğini teşhis etmeye çalışıyorum (ne yazık ki gdb ile çalıştırıldığında istisna atılmıyor). Ancak, istisnai ne() basar, sadece "std :: exception" dizesini alırım. Bu, standart kitaplıktaki herhangi bir şeye özgü mü yoksa standart bir çok istisna mı döndürüyor? İşte baskıya yapıyorum ne:std :: exception'ın what() "std :: exception" değerini döndürür

} catch (const std::exception & ex) { 
     std::cout << ex.what() << std::endl; 
    } 

çıkış adildir: Ayrıca

std::exception 

, ben oldukça büyük bir kod tabanı çalışıyorum, geliyor olması mümkündür Sonumuzun bir istisnası olsa da, normal arama teknikleriyle henüz bulamamış bulunmaktayım, bu yüzden standart kütüphanelerden geliyorum.

Eğer ilgili ise g ++ 4.8 kullanıyorum.

+0

Gdb'ye yükleyebileceğiniz bir çekirdek dökümü alıp bir backtrace açın mı? –

+0

Özel durum nasıl atılır? Nasıl atılır? Hangi istisna atılır? Lütfen [Minimal, Tam ve Doğrulanabilir Örnek] (http://stackoverflow.com/help/mcve) oluşturun ve bize gösterin. –

+0

Bir GCC kitaplığı istisnasının olağandışı görünmesi - std :: runtime_error, std :: length_error vb. Gibi daha özel türetilmiş bir sınıf olmasını beklerim (bunlardan biri (http: //en.cppreference). com/w/cpp/error/exception)) ile .what() 'iletir. Bunun muhtemelen kendi kod tabanından olduğunu düşünüyorum. yardımcı olmayabilir, ama ben olsaydı ben \ kendi kodunda + std :: exception'' s ve bu bir şey gitmezse eğer GCC deneyebilirsiniz atmak ' 'bir tekrarlı grep çalışacaktı ediyorum başlıkları. –

cevap

3
C++ istisnaları, Java istisnalarından tamamen farklıdır.

C++ tamamen keyfidir ve ne() tarafından döndürülen dize uygulama tanımlı belirtir:

virtual const char* what() const noexcept; 

Returns: An implementation-defined ntbs. 
Remarks: The message may be a null-terminated multibyte string 
(17.5.2.1.4.2), suitable for conversion 
and display as a wstring (21.3, 22.4.1.4). The return value remains 
valid until the exception object 
from which it is obtained is destroyed or a non-const member 
function of the exception object is called. 

alıyoruz dönüş değeri, "std :: istisna" mükemmel uyumludur C++ standardı.

Java'nın yaptığı gibi, onları yakaladıktan sonra nereye atıldığını tam olarak bildirmek için C++ istisnalarına güvenmeyin. Bu, C++ standardının kapsamı dışındadır. C++ 'da, bir istisna, yürütme kontrol akışını aktarmak için bir mekanizmadan başka bir şey değildir.

Bunu söyledikten sonra: Birçok C++ uygulaması, geçerli yığın backtrace'ini dökümlemek için bazı uygulamalara özgü mekanizmalar sunacaktır, çalışma zamanı kitaplığının yeteneklerinin en iyisine. Daha fazla bilgi için C++ derleyicinizin belgelerine bakın. Gk, örneğin, backtrace() tarafından döndürülen işlenmemiş adresleri sembollere dönüştürmek için bazı gcc dahili işlevleriyle birlikte backtrace() işlevini ve sembolleri deşifre etmek için diğer işlevleri sunar. Bunu kullanarak, Java'nın istisna işleme için kaba bir analog düzenlenebilir; gcc'nin uygulaması mükemmel olmamasına ve bazı işlevsel deliklere sahip olmasına ve aynı zamanda peşin planlamayı ve kurucuların geçerli yığın çerçevesini yakaladığı özel istisna sınıfları gerektirmesine rağmen (istisnanın gerçekte atılmasına neden olur); ve yakalandıktan sonra, atılan istisna sınıfı örneği yakalanan backtrace bilgisi için incelenebilir.

Fakat bu durum şu anki durumunuza gerçekten yardımcı olmuyor. Önerdiğim gibi C++ derleyicinizin belgelerini kontrol etmenizi ve hata ayıklayıcınızın özelliklerini araştırmanızı öneririm. Bir C++ hata ayıklayıcısı, herhangi bir özel durum atıldığında ve yakalanmadan önce bir kesme noktası ayarlamanıza izin vermelidir, böylece istisna oluştuğunda, hata ayıklayıcı aracılığıyla yığın backtrace'i inceleyebilirsiniz.

+0

Teşekkürler, backtrace'e bir göz atacağım. Bu beni bütün kod tabanı üzerinden ikili bir arama yapmaktan kurtarabilir! – Pace

+0

backtrace yardımcı oldu (sembolleri doğru bir şekilde çözemedim, ancak onları kurtarabildim ve daha sonra konumları almak için gdb'ye besledim) ve sonunda problemin köküne doğru yol aldım. Teşekkürler. – Pace

+0

Bu yanıt, istisna iletileri genellikle C++ uygulamasında tanımlanmış gibi ses çıkarır, ancak bu yalnızca 'std :: exception' temel sınıfı için geçerlidir ve std :: runtime_error 'gibi türetilmiş sınıflara değil,' what' nedir? Yapıcıya ilettiğiniz dizeyi iade etmeyi garantiledi. Örneğin, §22.2.7/3 diyor: * "Hedefşartlar:' strcmp (Ne(), what_arg.c_str()) == 0' *". Ben 'std :: runtime_error X ("foo")' oluşturursanız IOW, ardından '' ' "std :: istisna" what' vermemelidir. –

10

Bunun nedeni, iki şey olabilir:

  1. Birisi az yerde throw std::exception() yapar, çok yararlı değildir.

  2. std::exception'dan türetilen bir sınıf std::exception'a kopyalanır. Bu, Object Slicing adı verilen bir sorundur.

Sadece ikinci hatayı kendim yaptım.

try 
{ 
    // Some Boost stuff 
} 
catch (std::exception e) 
{ 
    cerr << e.what() << endl; 
} 

Sen std::exception& e yapmak emin olmalısınız: Bu kodu vardı. Bu hatayı yapmadığınızı biliyorum, ancak kodun içinde başka bir kişi daha var (veya Google’dan gelen biri).

+2

Teşekkürler, & eksik. – Tuntable