Bir çalışma zamanı hatası varsa ne olur?


17

Bir programda çalışma zamanı hatası varsa ne olur? Programın yürütülmesi duracak mı? Arduino'nun hatanın ne olduğunu söylemesini sağlamanın bir yolu var mı?

Yanıtlar:


21

İlk olarak, neyin yanlış gidebileceğine dair birkaç örnek görelim.

Başlatılmamış yerel değişkenler

void setup() {
  int status;
  pinMode(13, OUTPUT);
  digitalWrite(13, status);
} 

Yorumlarda Edgar Bonet tarafından belirtildiği gibi status, yukarıdaki koddaki gibi yerel değişkenler C ++ derleyicisi tarafından örtük olarak başlatılmaz. Dolayısıyla, yukarıdaki kodun sonucu belirsizdir. Bundan kaçınmak için her zaman yerel değişkenlerinize değer atadığınızdan emin olun.

Küresel ve statik değişkenlerle işler biraz farklı:

Global ve statik değişkenlerin C standardı ile 0 olarak başlatılması garanti edilir.

Kaynak: AVR Libc Başvuru Kılavuzu - Sık Sorulan Sorular - Tüm değişkenlerimi başlatmamalı mıyım?

Bu, kodunuzda 0 olarak başlatma konusunda endişelenmemeniz gerektiği anlamına gelir. Başlangıçta bellek israfına neden olabileceğinden, aslında bundan kaçınmalısınız. Bunları yalnızca 0 dışındaki değerlere sıfırlayın.

Bellek taşması

int array[10];
int v = array[100];
array[-100] = 10;

Buradaki ilk sorun, v'ye neyin atanacağını bilmemenizdir, ancak daha da kötüsü, -100 konumunun atamasıyla ne karıştırdığınızı bilmemenizdir array.

Yasadışı bir talimata atla

void doSomething( void ) { 
    for (int i = 0; i < 1000; i++); 
}

void setup () 
{
    void (*funcPtr)( void );

    funcPtr = &doSomething;
    funcPtr(); // calls doSomething();

    funcPtr = NULL;
    funcPtr(); // undefined behavior
}

İlk çağrı funcPtr()aslında bir çağrı olacaktır doSomething(). İkincisi gibi çağrılar tanımlanmamış davranışa yol açabilir.

Olabilecek diğer kötü şeyler

Örneğin, RAM'iniz tükenebilir. Başka. Her durumda, programınızın çalışmaya devam edeceğini düşünüyorum, muhtemelen istediğiniz gibi değil.

Koruma Türleri

Bilgisayar sistemlerinde, bunlar gibi sorunlar genellikle çeşitli düzeylerde ele alınır:

  1. Derleyici tarafından
  2. Programlama dili çalışma zamanına göre (örneğin Java'da olduğu gibi).
  3. İşletim sistemi veya işlemci tarafından (belleğiniz programınıza ayrılmış adres alanının sınırları dışında bir konuma erişirse, işletim sistemi veya işlemci bunu önlemek için güvenlik mekanizmalarına sahip olabilir)

Arduino'ların sadece derleyici koruması sınırlıdır ve muhtemelen başka hiçbir şey yoktur. İyi haber, çok görevli olmamalarıdır, bu yüzden etkilenen tek program sizindir. Her durumda, bu hatalardan herhangi biri düzensiz davranışlara yol açacaktır.

Cevaplar

Varsayımlar yukarıda bahsettiğim sorunların tümü çalışma zamanı sorunudur.

Bir programda çalışma zamanı hatası varsa ne olur?

Program devam edecek ve ne olacağı çalışma zamanı hatasının yan etkilerine bağlı olacaktır. Null fonksiyon işaretçisine yapılan bir çağrı muhtemelen programın bilinmeyen bir konuma atlamasını sağlayacaktır.

Programın yürütülmesi duracak mı?

Hayır, sanki olağanüstü bir şey olmamış gibi devam edecek, muhtemelen yapmayı istemediğiniz şeyi yapıyor olacak. Sıfırlanabilir veya düzensiz hareket edebilir. Bazı girişleri çıkışlara dönüştürebilir ve bir veya iki sensör yakabilir (ancak bu pek olası değildir ).

Arduino'nun hatanın ne olduğunu söylemesini sağlamanın bir yolu var mı?

Ben öyle düşünmüyorum. Daha önce söylediğim gibi, koruma mekanizmaları orada değil. Dilden çalışma zamanı desteği yok, işletim sistemi yok, sınır dışı bellek erişimi için donanım kontrolü yok (önyükleyici de sayılmaz). Programınıza dikkat etmeniz ve muhtemelen kendi güvenlik ağlarınızı ayarlamanız gerekir.

Koruma eksikliğinin nedeni muhtemelen Arduino denetleyicilerinin çok ucuz olması, çok az belleğe sahip olması ve çok önemli bir şey çalıştırmaması gerektiğidir (evet, AVR tarafından normalde kullanılan MCU'ları kullanmamanız için bir yerde bir feragat var gibi görünüyor. Yaşam destek sistemlerinde Arduino).


1
Harika! Arduino'da gördüğüm en iyi cevap.
Şapkalı Adam

1
Teşekkürler!! Bence olabildiğince büyük cevaplar vermeye çalışmalıyız. Ama bu, benim gibi cevaplara bakabilecek ve göze çarpan hatalar bulabilecek çok sayıda GERÇEK EE UZMANINA sahip olmamamız beni biraz endişelendiriyor. Aslında, AVR MCU'lar hakkında fazla bir şey bilmememe rağmen cevabı yayınlamamın nedeni budur. Bunu düzeltecek birini bulup bulamayacağımızı görmek için. Benim gibi akıllı pentlerin doğru olmayan şeyler söylemesini ve ondan kurtulmasını istemiyoruz. Ancak bu muhtemelen Meta sitesi için bir tartışmadır.
Ricardo

5
@Ricardo - Yapacağım bir yorum açıkça başlatılmamış değişkenlerin mutlaka başlatılmamış olmasıdır. İşlevlerin dışında tanımlanan değişkenler genellikle "otomatik depolama süresi" olarak adlandırılan değişkenlere sahiptir ve bu değerler varsayılan olarak sıfıra sıfırlanır. Daha fazla bilgi için en.cppreference.com/w/cpp/language/default_initialization adresine bakın . Başlatma davranışı, muhtemelen güvenilmesi gereken kadar karmaşıktır, ancak battaniye ifadeleri yapmak muhtemelen harika bir fikir değildir.
Connor Wolf

1
Ayrıca, sıfırlama veya başlatma sırasında SRAM 0 olarak başlatılır, böylece tehlikeli bir şekilde yaşamak istiyorsanız, başlatılmamış değişkenler hakkında bazı bilinçli tahminler yapabilirsiniz . Sen olmamalıdır güvenmek bu davranışı üzerinde, ama ilginçtir.
Connor Wolf

1
SRAM'ı burada bitirdiğinizde ilginç bir örnek var: electronics.stackexchange.com/questions/42049/… . Temel olarak, yığın yığının bir kısmını gizler veya tersi de geçerlidir. Bu, yığın çerçevesinin bir kısmını bozma (kesme işlevi döndürmeleri vb.) Veya değişkenlere geçersiz veriler yazma gibi ilginç şeyler yapabilir.
Connor Wolf

9

Çalışma zamanı istisnası yoktur. Yalnızca tanımlanmamış davranış var.

Gerçekten, hiçbir istisnası yoktur hiç . Geçersiz bir işlem gerçekleştirmeye çalışırsanız, sonuçları bilinmeyecektir.

Ne dışında hiç kontrol yok çalışma zamanı yoktur sen uygulamak. Programınız çıplak metal donanım üzerinde çalışıyor. Her zaman ring-0'da koşmanın Masaüstü eşdeğeri , çünkü ATmega'nın halkaları yok .


6

MCU'yu düzensiz durumdan alabilen bir mekanizma vardır ve bu gözlemci zamanlayıcıdır . Bir döngüde tekrar tekrar çalışacak, sabit bir süreden daha uzun sürmeyecek bir kod uyguluyorsanız, bu süreyi bekçi dönemi olarak ayarlayabilir ve zamanlayıcıyı etkinleştirebilirsiniz.

Ardından, döngüdeki zamanlayıcıyı tekrar tekrar sıfırlamanız gerekir. Kodunuz hiç bitmeyecek bir durum döngüsünde donarsa, gözlemci sıfıra kadar sayar ve sonunda MCU'yu sıfırlar.

Bu şekilde veri kaybedersiniz, ancak AVR WDT'yi kesme modunda çalıştırırsanız, MCU'yu sıfırlamadan önce bazı verileri saklayabilirsiniz.

Böylece bekçi zamanlayıcısı, kodunuzu zaman zaman istenmeyen sonsuz döngülerden koruyabilir.

Belgeler: AVR132: Geliştirilmiş Gözcü Zamanlayıcısını Kullanma


5

Böyle bir şey için bir donanım hata ayıklayıcısına ihtiyacınız olacak. Ancak genellikle programın beklediğiniz gibi davranmadığını görürsünüz ve sorunu tanımlamak için kodun bu bölümüne bakmanız gerekir.

Bunu yapmanın yaygın / hızlı / kolay bir yolu, değişkenlerin değerlerini veya sadece herhangi bir şeyi yazdırmak için yazdırma ifadeleri eklemektir, böylece program kodda o noktaya sorunsuz bir şekilde ulaşır. Bu, sorunu daha fazla izole etmenize yardımcı olacaktır.

VisualMicro'nun yerleşik bazı hata ayıklama işlevleri olduğuna inanıyorum .


3

AVR CPU'nun herhangi bir hata algılama veya kurtarma aracı olmadığını varsayarım. Sadece durabilir veya hatayı ve sonuçlarını görmezden gelebilir. Sachleen'in dediği gibi, programınıza bir işlemin ortasında çalışıp çalışmadığını test etmek için bazı hata ayıklama ifadeleri eklemelisiniz. Bir emulaor kullanır ve kesme noktaları ayarlarsanız, kolayca bir sorun bulabilirsiniz.


-2

Arduino yeniden başlatılacak (yani yeniden başlatılacak setup()ve loop()).


1
Şart değil. Bir çalışma zamanı hatası, programı yeniden başlatmadan döngüye girebilir.
Nick Gammon
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.