보호 된 메모리 전에 세그먼트 화 오류를 어떻게 디버깅 했습니까?


20

이제 C에서 포인터로 프로그래밍 실수를하면 멋진 세그먼테이션 오류가 발생하고 프로그램이 충돌하고 디버거가 오류가 발생한 위치를 알려줄 수도 있습니다.

메모리 보호 기능을 사용할 수 없었을 때 어떻게 그렇게 했습니까? DOS 프로그래머가 실수를해서 실수로 전체 OS를 망가 뜨리는 것을 볼 수 있습니다. 가상화를 사용할 수 없었으므로 다시 시작하고 다시 시도하기 만하면됩니다. 정말 그렇게 되었습니까?


4
그렇습니다. 컴퓨터가 무작위로 재부팅되어 자주 발생했습니다. 메모리 보호는 훌륭한 것입니다 :)
Rocklan

7
메모리를 보호하지 않으면 분할 오류와 같은 것은 없습니다. 물론, 당신이 메모리를 보호하더라도, 당신은 여전히 ​​자신의 공간을 방해 할 수 있습니다. OS는 신경 쓰지 않습니다.
Blrfl

3
지금도 많은 포인터 실수로 멋진 segfault가 발생하지 않습니다.
코드 InChaos

1
DOS 당시에는 보호 된 메모리가 이미 다른 OS에 존재했습니다.
mouviciel

답변:


36

DOS 프로그래머가 실수를해서 실수로 전체 OS를 망가 뜨리는 것을 볼 수 있습니다.

예, 그것은 거의 일어난 일입니다. 메모리 맵이있는 대부분의 시스템에서 위치 0은 유효하지 않은 것으로 표시되었으므로 가장 일반적인 경우이므로 널 포인터를 쉽게 감지 할 수 있습니다. 그러나 다른 많은 경우가 있었으며 그들은 혼란을 야기했습니다.

괴짜처럼 들릴 위험이 있기 때문에 디버깅에 대한 현재의 초점은 과거의 방식이 아니라는 점을 지적해야합니다. 이전에는 잘못된 프로그램에서 버그를 제거하기보다는 올바른 프로그램을 작성하기 위해 훨씬 더 많은 노력을 기울였습니다. 그 중 일부는 이것이 우리의 목표 였지만 도구가 일을 어렵게 만들었 기 때문입니다. 대화식 디버거의 이점없이 IDE가 아닌 종이나 펀치 카드로 프로그램을 작성하십시오. 정확성을 맛볼 수 있습니다.


3
사실, 나는 "오래된 간헐천"이 내 질문에 대답하기를 바랐다. 직접적인 경험을 능가하는 것은 없습니다. 감사.
Bart Friederichs

6
동료가 디버그 세션을 위해 예약하지 않았다고 가정 할 때 매일 02:00부터 06:00까지 디버깅 할 수있는 하드웨어를 사용할 수있을 때 코드를 작성해보십시오.
MSalters

@MSalters 참으로! 내 첫 직장에서, 우리는 또한 0700에서 1900 일요일에 슬롯을 예약 할 수 - 진짜 치료, :-) 당신에게 줄께요
로스 패터슨을

2
대학에서 집으로 여행 하는 종이에 첫 프로그램 작성했던 것을 기억 합니다. 다음 날 내가 그것을 펀칭하고 실행할 수 있었을 때, 그것은 흠이 없었다 ;-)
Jan Doggen

1
@JanDoggen, 저도 마찬가지입니다. 한 번만 시도하면 실제로 시도해 볼 수 있습니다.
nalply

23

나의 시대에, 우리는 기억 보호와 그 멋진 사업을 모두하지 않았다! 우리는 printf를 사용하여 프로그램의 위치를 ​​결정 했으며 좋아했습니다 !

모든 진지함에도 불구하고 그것은 보통 우리가 더 조심 스러웠다는 것을 의미했습니다. malloc이 호출되는 곳에서는 프로그램의 다른 곳에서 무료가 필요했고 문제의 경우 분명히 지적했듯이 세그먼테이션 결함은 유용한 오류가 아니기 때문에 그러한 검사는 엄격했습니다.

그러한 오류의 경우, 가능한 세분화 오류 (printf를 사용하여)가 발생 하는 시점 을 이해 하고 코드를 살펴보면 해당 시점에서 메모리에 대한 액세스가 유효하지 않은 이유를 판별하고 그 뒤로 거꾸로 작업하는 것이 가장 좋습니다.

본질적으로 디버거를 사용하여 오류가 발생하는 시점을 결정한다는 점을 제외하고는 오늘도 같은 일이 발생하지만 오류가 발생한 이유 를 이해해야 하며 오류가 발생한 줄을 찾는 것만 큼 항상 간단하지는 않습니다. 오류로 인해 연쇄 반응과 같은 오류가 발생하고 그 당시 C 프로그래머라면 코딩 시간의 20 %를 소비하고 나머지 시간에는 머리카락을 버그를 수정하는 데 소비했습니다.


2
Mallocs를 해방하십시오!
Chris

1
때때로 심지어 오늘날에도 심지어 콜 스택과 가변 상태조차 도대체 무엇이 잘못되었는지와 그것을 고치는 방법을 결정하는 데 전혀 쓸모가 없습니다. 가능한 많은 수의 상태를 가진 복잡한 소프트웨어가있는 경우에 특히 그렇습니다. 일부는 상호 의존적이며 일부는 상호 배타적입니다. 어느 곳에 나 하나의 스트레이 쓰기 가 가능하며 보장 된 전제 조건에 대한 생략 된 주장은 바로 당신을 가져올 수 있습니다.
CVn

1
@ MichaelKjörling, 나는 프로그램에서 오류를 발견하는 것과 관련하여 오류 트리거를 찾는 것에 대해서만 진전을 보였지만 여전히 이러한 오류의 원인을 밝히기 위해 갈 길이 멀다고 생각합니다. 주장은 확실히 제정신을 유지하는 데 도움이됩니다. :)
Neil

6

잘 ..

segfault는 무언가 잘못되었다는 정말 좋은 지표이지만 여전히 근본 원인을 찾아야합니다. 그래서 당신이 질문을한다면 당신은 그 답이 오늘날보다 크게 다르지 않은 것보다 근본 원인을 어떻게 찾을 수 있습니까? 물론 언어와 도구를 사용하기가 더 쉬워졌지만 일반적인 택틱은 동일합니다.

  • 로깅은 문제가있는 영역을 찾는 데 도움이됩니다. 이진 검색 printf는 그 형태입니다.
  • 디버깅, 단계별, 중단 점 및 시계
  • 더 나은 이해를위한 리팩토링
  • 코드를 열심히 쳐다보다
  • 메모리 / 코어 덤프를보십시오
  • 다른 데이터로 먹이기
  • 다른 사람들에게 보여주기
  • 포인터가없는 언어로 전환하십시오 (그리고 새로운 문제 세트) ...

보다 추상적 인 수준에서는 세 가지 접근 방식이 있습니다. 1. 코드 작업 2. 실행하는 동안 프로그램보기 3. 어리석은 일을 한 후 결과보기

btw 포인터 오류가 segfault를 만들 필요는 없습니다.

Amiga 프로그래머로서 나는 거의 모든 것을 사용했습니다. 그리고 예는 일반적인 관행에서 다시 시작합니다.


4

Fortran 배치 작업을 실행하는 IBM 360에서는 16 진 코어 덤프를 얻었습니다. 이러한 덤프는 1 인치 두께의 부채꼴 녹색 및 흰색 프린터 용지 일 수 있습니다. 레지스터가 무엇인지 알려주고 거기서부터 프로그램이 무엇을하고 있는지 역 추적 할 수있었습니다. 각 서브 루틴을 찾아서 리턴 주소가 저장된 위치를 파악하여 컨텍스트를 볼 수 있습니다. 프로그램의 어셈블러 목록을 작성하는 데 도움이됩니다.


2

한때 유명한 Windows 3.1 프레젠테이션 소프트웨어에서 버그 수정 작업을하고있었습니다.

나는 그것이 발생했을 때 죽음의 블루 스크린을 일으킨 버그가있었습니다.

버그는 특정 루프가 1000 번 이상 실행될 때만 발생했습니다. 디버거의 고급 기능을 사용하여 중단 점을 1000 회 통과시킨 다음 신중하게 프로그램을 단계별로 진행했습니다. Windows Blue Screened 버그가 포함 된 함수 호출을 너무 멀리하거나 건너 뛸 때마다.

마지막으로 며칠간의 작업 끝에 메모리가 부족한 함수로 범위를 좁히고 오류 메시지를 표시하는 대신 오류 메시지를 버퍼에 추가했습니다. 매번 반복 할 때마다 중요한 내용을 덮어 쓰고 Windows가 휴지통에 올 때까지 더 많은 메모리를 낭비했습니다.

디버깅 기술과 인내가 해결책이었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.