런타임 오류가 발생하면 어떻게됩니까?


17

프로그램에 런타임 오류가 있으면 어떻게됩니까? 프로그램 실행이 중단됩니까? Arduino에 오류가 무엇인지 알려주는 방법이 있습니까?

답변:


21

먼저 무엇이 잘못 될 수 있는지 몇 가지 예를 살펴 보겠습니다.

초기화되지 않은 지역 변수

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

주석에서 Edgar Bonet이 지적한 것처럼 status위 코드 와 같은 로컬 변수 는 C ++ 컴파일러에 의해 암시 적으로 초기화되지 않습니다. 따라서 위 코드의 결과는 불확실합니다. 이를 피하려면 항상 지역 변수에 값을 지정하십시오.

전역 변수와 정적 변수는 약간 다릅니다.

글로벌 및 정적 변수는 C 표준에 의해 0으로 초기화됩니다.

출처 : AVR Libc Reference Manual-질문과 대답-모든 변수를 초기화하지 않아야합니까?

즉, 코드에서 0으로 초기화하는 것에 대해 걱정할 필요가 없습니다. 실제로 초기화하면 메모리가 낭비 될 수 있으므로 실제로 피해야합니다. 0 이외의 값으로 만 초기화하십시오.

메모리 오버 플로우

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

여기서 첫 번째 문제는 v에 할당 할 대상을 모르지만 -100의 위치 -100에 대한 할당으로 엉망인 것을 알지 못한다는 것입니다 array.

불법 명령으로 이동

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
}

에 대한 첫 번째 호출 funcPtr()은 실제로에 대한 호출 doSomething()입니다. 두 번째와 같은 호출은 정의되지 않은 동작으로 이어질 수 있습니다.

일어날 수있는 다른 나쁜 일들

예를 들어, RAM이 부족할 수 있습니다. 다른 것. 어쨌든, 나는 당신의 프로그램이 의도 한 방식이 아닌 계속 실행될 것이라고 생각합니다.

보호의 종류

컴퓨터 시스템에서 이와 같은 문제는 일반적으로 다양한 수준에서 처리됩니다.

  1. 컴파일러에 의해
  2. 프로그래밍 언어 런타임 (예 : Java)
  3. 운영 체제 또는 프로세서에 의해 (메모리가 프로그램에 예약 된 주소 공간의 경계를 벗어난 위치에 액세스하는 경우 OS 또는 프로세서는이를 방지하기위한 안전 메커니즘을 가질 수 있음)

Arduino는 컴파일러에 대한 보호 기능이 제한적이며 다른 것은 없습니다. 좋은 소식은 멀티 태스킹이 아니기 때문에 영향을받는 유일한 프로그램은 귀하의 것입니다. 어쨌든 이러한 버그 중 하나라도 이상하게 동작합니다.

답변

위에서 언급 한 모든 문제는 런타임 문제라고 가정합니다.

프로그램에 런타임 오류가 있으면 어떻게됩니까?

프로그램은 계속 진행되며 실행 오류는 런타임 오류의 부작용에 따라 달라집니다. 널 함수 포인터를 호출하면 프로그램이 알 수없는 위치로 이동합니다.

프로그램 실행이 중단됩니까?

아니, 그것은 당신이 의도하지 않은 일을하는 특별한 일이없는 것처럼 계속 진행될 것입니다. 재설정되거나 잘못 작동 할 수 있습니다. 일부 입력을 출력으로 변환하여 센서를 태울 수 있습니다 (그러나 가능성은 거의 없습니다 ).

Arduino에 오류가 무엇인지 알려주는 방법이 있습니까?

나는 그렇게 생각하지 않습니다. 앞서 말했듯이 보호 메커니즘은 없습니다. 언어에서 OS를 지원하지 않으며 OS도없고 하드웨어가 범위를 벗어난 메모리 액세스를 검사하지 않습니다 (부트 로더도 계산하지 않음). 프로그램에주의를 기울이고 자신 만의 안전망을 설정해야합니다.

보호 기능이 부족한 이유는 아마도 Arduino 컨트롤러가 너무 싸고 메모리가 너무 적고 너무 중요한 것을 실행하지 않아야하기 때문일 것입니다 (예, AVR은 일반적으로 사용하는 MCU를 사용하지 않는 곳에서 AVR에 고지 사항이있는 것 같습니다) 생명 유지 시스템의 Arduino).


1
큰! 내가 지금까지 Arduino.SE에서 본 최고의 답변!
모자와 사람

1
감사!! 가능한 한 많은 답변을 드리려고 노력해야한다고 생각합니다. 그러나 그것은 저와 같은 대답을보고 눈에 띄는 실수를 찾을 수있는 많은 REEE 전문가가 없다는 사실에 대해 조금 걱정합니다. 실제로 AVR MCU에 대해 많이 알지 못하더라도 답변을 게시 한 이유입니다. 그것은 우리가 누군가에게 그것을 고치도록하는 것입니다. 우리는 옳지 않은 말을하고 도망 치는 것과 같은 현명한 헛소리를 원하지 않습니다. 그러나 아마도 메타 사이트에 대한 토론 일 것입니다.
Ricardo

5
@Ricardo-내가 언급 한 의견은 명시 적으로 초기화 되지 않은 변수가 반드시 초기화되지 않은 것은 아닙니다 . 함수 외부에서 정의 된 변수에는 일반적으로 "자동 저장 기간"이라는 용어가 있으며 기본값은 0으로 초기화됩니다. 자세한 내용은 en.cppreference.com/w/cpp/language/default_initialization 을 참조하십시오. 초기화 동작은 의존 아마 위험하다는 복잡한 충분하지만, 담요 문을 만드는 것은 아마 좋은 생각이 아니다.
코너 울프

1
당신이 할 수 있도록 또한, SRAM은, 리셋 또는 시작할 때 0으로 초기화 일부 는 위험하게 살고 싶은 경우, 초기화되지 않은 변수에 대한 정보를 추측. 이 행동에 의존 해서는 안되지만 흥미 롭습니다.
코너 울프

1
: 여기 SRAM이 부족할 때 발생하는 흥미로운 예입니다 electronics.stackexchange.com/questions/42049/...은 . 기본적으로 스택 클로버는 힙의 일부이거나 그 반대입니다. 이는 스택 프레임의 일부가 손상되거나 (반복 함수 리턴 등) 변수에 유효하지 않은 데이터를 쓰는 것과 같은 흥미로운 작업을 수행 할 수 있습니다.
코너 울프

9

런타임 예외는 없습니다. 정의되지 않은 동작 만 있습니다.

정말, 예외가없는 전혀은 . 잘못된 작업을 수행하려고하면 결과를 알 수 없습니다.

무엇을 제외한 모든에서 확인에는 런타임 없다 당신이 구현은. 프로그램이 베어 메탈 하드웨어에서 실행 중입니다. ATmega 에는 ring이 없기 때문에 항상 ring-0 으로 실행되는 데스크톱 입니다.


6

MCU를 불규칙한 상태에서 얻을 수있는 메커니즘은 워치 독 타이머 입니다. 루프에서 반복적으로 실행되는 코드를 일정 시간 이상 실행하지 않는 코드를 구현하는 경우이 시간을 워치 독 기간으로 설정하고 타이머를 활성화 할 수 있습니다.

그런 다음 루프에서 타이머를 반복해서 재설정해야합니다. 종료되지 않는 조건 루프에서 코드가 정지되면 워치 독은 0으로 카운트되어 결국 MCU를 재설정합니다.

이렇게하면 데이터가 손실되지만 AVR WDT를 인터럽트 모드에서 실행하면 MCU를 재설정하기 전에 일부 데이터를 저장할 수 있습니다.

워치 독 타이머는 의도하지 않은 무한 루프로부터 코드를 보호 할 수 있습니다.

설명서 : AVR132 : Enhanced Watchdog Timer 사용


5

이와 같은 하드웨어 디버거가 필요합니다. 그러나 일반적으로 프로그램이 예상대로 작동하지 않는 것을 볼 수 있으며 문제를 식별하기 위해 해당 코드 섹션을 살펴 봐야합니다.

이 작업을 수행하는 일반적인 / 빠른 / 쉬운 방법은 print 문을 추가하여 변수의 값을 인쇄하거나 프로그램이 문제없이 코드의 해당 지점에 도달하도록하는 것입니다. 이렇게하면 문제를 더 격리 할 수 ​​있습니다.

VisualMicro 에는 디버깅 기능이 내장되어 있다고 생각 합니다.


3

AVR CPU에 오류 감지 또는 복구 도구가 없다고 가정합니다. 오류와 결과를 무시하거나 계속 무시할 수 있습니다. sachleen이 말했듯이, 작업 중에 데이터를 출력하는 디버그 명령문을 프로그램에 추가하여 작동하는지 테스트해야합니다. 에뮬레이터를 사용하고 중단 점을 설정하면 문제를 쉽게 찾을 수 있습니다.


-2

Arduino가 재부팅됩니다 (즉, 다시 시작 setup()하고 loop()).


1
반드시 그런 것은 아닙니다. 런타임 오류로 인해 재부팅하지 않고 프로그램이 루프 상태가 될 수 있습니다.
Nick Gammon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.