시스템 튜토리얼 리눅스 Linux 커널의 예외 정보: Oops에 대한 자세한 설명

Linux 커널의 예외 정보: Oops에 대한 자세한 설명

Feb 10, 2024 pm 12:00 PM
linux 리눅스 튜토리얼 리눅스 시스템 리눅스 명령 쉘 스크립트 overflow 임베디드리눅스 리눅스 시작하기 리눅스 학습

Oops는 Linux 커널의 특수 오류 메시지로 널 포인터 역참조, 불법 메모리 액세스, 0으로 나누기 오류 등 커널에서 치명적이지 않은 예외가 발생했음을 나타내는 데 사용됩니다. Oops가 발생한다는 것은 일반적으로 커널에 버그가 있거나 드라이버에 문제가 있어 시스템이 불안정하거나 충돌을 일으킬 수 있음을 의미합니다. 이번 글에서는 웁스의 형식, 내용, 이유, 분류 등 리눅스 커널에서의 웁스의 원리와 특징을 소개하고, 사용법과 주의사항에 대한 예를 들어보겠습니다.

Linux 커널의 예외 정보: Oops에 대한 자세한 설명

Linux 커널 개발에서 Oops란 무엇인가요? 사실 말하는 주인공이 리눅스가 된다는 점 외에는 위의 설명과 본질적인 차이는 없다. 좀 더 치명적인 문제가 발생하면 Linux 커널은 "죄송합니다. 제가 망쳤습니다."라고 변명하듯이 말할 것입니다. 커널 패닉이 발생하면 Linux 커널은 Oops 정보를 인쇄하고 현재 레지스터 상태, 스택 콘텐츠 및 전체 호출 추적을 표시하여 오류를 찾는 데 도움이 됩니다.

이제 예를 살펴보겠습니다. 이 기사의 주인공인 앗, 이 예제의 유일한 기능은 널 포인터 참조 오류를 생성하는 것입니다.

으아아아

분명히 오류는 8번째 줄입니다.

다음으로 이 모듈을 컴파일하고 insmod를 사용하여 커널 공간에 삽입했습니다. 예상대로 Oops가 나타났습니다.

[ 100.243737] 버그: (null)

에서 커널 NULL 포인터 역참조를 처리할 수 없습니다.

[100.244985] IP: [] hello_init+0x5/0x11 [안녕]

[ 100.262266] *pde = 00000000

[100.288395] 이런: 0002 [#1] SMP

[ 100.305468] 마지막 sysfs 파일: /sys/devices/virtual/sound/timer/uevent

[ 100.325955] 연결된 모듈: hello(+) vmblock vsock vmmemctl vmhgfs acpiphp snd_ens1371 gameport snd_ac97_codec ac97_bus snd_pcm_oss snd_mixer_oss snd_pcm snd_seq_dummy snd_seq_oss snd_se q_mid i snd_rawmidi snd_seq_midi_event snd_seq snd_timer snd_seq_device ppdev psmouse serio_raw fbcon 타일블릿 글꼴 bitblit Softcursor snd parport_pc soundcore snd_page_alloc vmci i2c_piix4 vga16fb vgastate intel_agp agpgart shpchp lp parport 플로피 pcnet32 mii mptspi mptscsih mptbase scsi_transport_spi vmxnet

[ 100.472178] [ 100.494931] Pid: 1586, comm: insmod 오염되지 않음 (2.6.32-21-generic #32-Ubuntu) VMware 가상 플랫폼

[100.540018] EIP: 0060:[] EFLAGS: 00010246 CPU: 0

[ 100.562844] EIP는 hello_init+0x5/0x11 [hello]에 있습니다.

[ 100.584351] EAX: 00000000 EBX: ffffffffc ECX: f82cf040 EDX: 00000001

[ 100.609358] ESI: f82cf040 EDI: 00000000 EBP: f1b9ff5c ESP: f1b9ff5c

[ 100.631467] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068

[ 100.657664] insmod 프로세스(pid: 1586, ti=f1b9e000 task=f137b340 task.ti=f1b9e000)

[100.706083] 스택:

[ 100.731783] f1b9ff88 c0101131 f82cf040 c076d240 fffffffc f82cf040 0072cff4 f82d2000

[ 100.759324]fffffffc f82cf040 0072cff4 f1b9ffac c0182340 f19638f8 f137b340 f19638c0

[100.811396]00000004 09cc9018 09cc9018 00020000 f1b9e000 c01033ec 09cc9018 00015324

[100.891922] 통화 추적:

[ 100.916257] [] ? do_one_initcall+0x31/0x190

[ 100.943670] [] ? hello_init+0x0/0x11 [안녕]

[ 100.970905] [] ?sys_init_module+0xb0/0x210

[ 100.995542] [] ?syscall_call+0x7/0xb

[ 101.024087] 코드: 05 00 00 00 00 01 00 00 00 5d c3 00 00 00 00 00 00 00 00 00 00

[ 101.079592] EIP: [] hello_init+0x5/0x11 [hello] SS:ESP 0068:f1b9ff5c

[101.134682] CR2: 0000000000000000

[ 101.158929] —[ 추적 종료 e294b69a66d752cb ]—

앗, 이게 어떤 버그인지 먼저 설명한 뒤, 버그가 발생한 위치를 지적했는데, "IP: [] hello_init+0x5/0x11 [hello]" 입니다.

여기서 문제 분석에 도움이 되는 보조 도구인 objdump를 사용해야 합니다. objdump를 사용하여 디스어셈블할 수 있으며 명령 형식은 다음과 같습니다.

objdump -S hello.o

下面是hello.o反汇编的结果,而且是和C代码混排的,非常的直观。

hello.o:     file format elf32-i386


Disassembly of section .init.text:

00000000 :
#include 
#include 

static int __init hello_init(void)
{
   0: 55                    push   %ebp
 int *p = 0;
 
 *p = 1;
 
 return 0;
}
   1: 31 c0                 xor    %eax,%eax
#include 
#include 

static int __init hello_init(void)
{
   3: 89 e5                 mov    %esp,%ebp
 int *p = 0;
 
 *p = 1;
   5: c7 05 00 00 00 00 01  movl   $0x1,0x0
   c: 00 00 00 
 
 return 0;
}
   f: 5d                    pop    %ebp
  10: c3                    ret    

Disassembly of section .exit.text:

00000000 :

static void __exit hello_exit(void)
{
   0: 55                    push   %ebp
   1: 89 e5                 mov    %esp,%ebp
   3: e8 fc ff ff ff        call   4 
 return;
}
   8: 5d                    pop    %ebp
   9: c3                    ret    
로그인 후 복사

对照Oops的提示,我们可以很清楚的看到,出错的位置hello_init+0x5的汇编代码是:

5:c7 05 00 00 00 00 01 movl   $0x1,0x0
로그인 후 복사

这句代码的作用是把数值1存入0这个地址,这个操作当然是非法的。

我们还能看到它对应的c代码是:

*p = 1;
로그인 후 복사

Bingo!在Oops的帮助下我们很快就解决了问题。

我们再回过头来检查一下上面的Oops,看看Linux内核还有没有给我们留下其他的有用信息。

Oops: 0002 [#1]

这里面,0002表示Oops的错误代码(写错误,发生在内核空间),#1表示这个错误发生一次。

Oops的错误代码根据错误的原因会有不同的定义,本文中的例子可以参考下面的定义(如果发现自己遇到的Oops和下面无法对应的话,最好去内核代码里查找):

* error_code:
* bit 0 == 0 means no page found, 1 means protection fault
* bit 1 == 0 means read, 1 means write
* bit 2 == 0 means kernel, 1 means user-mode
* bit 3 == 0 means data, 1 means instruction

有时候,Oops还会打印出Tainted信息。这个信息用来指出内核是因何种原因被tainted(直译为“玷污”)。具体的定义如下:

1: ‘G’ if all modules loaded have a GPL or compatible license, ‘P’ if any proprietary module has been loaded. Modules without a MODULE_LICENSE or with a MODULE_LICENSE that is not recognised by insmod as GPL compatible are assumed to be proprietary.
2: ‘F’ if any module was force loaded by “insmod -f”, ‘ ‘ if all modules were loaded normally.
3: ‘S’ if the oops occurred on an SMP kernel running on hardware that hasn’t been certified as safe to run multiprocessor. Currently this occurs only on various Athlons that are not SMP capable.
4: ‘R’ if a module was force unloaded by “rmmod -f”, ‘ ‘ if all modules were unloaded normally.
5: ‘M’ if any processor has reported a Machine Check Exception, ‘ ‘ if no Machine Check Exceptions have occurred.
6: ‘B’ if a page-release function has found a bad page reference or some unexpected page flags.
7: ‘U’ if a user or user application specifically requested that the Tainted flag be set, ‘ ‘ otherwise.
8: ‘D’ if the kernel has died recently, i.e. there was an OOPS or BUG.
9: ‘A’ if the ACPI table has been overridden.
10: ‘W’ if a warning has previously been issued by the kernel. (Though some warnings may set more specific taint flags.)
11: ‘C’ if a staging driver has been loaded.
12: ‘I’ if the kernel is working around a severe bug in the platform firmware (BIOS or similar).

기본적으로 이 Tainted 정보는 커널 개발자를 위해 예약되어 있습니다. 사용자가 Linux를 사용할 때 Oops를 발견하면 디버깅을 위해 Oops의 내용을 커널 개발자에게 보낼 수 있습니다. 이 Tainted 정보를 기반으로 커널 개발자는 커널 패닉이 발생할 때 커널이 실행되는 환경을 결정할 수 있습니다. 우리가 자체 드라이버를 디버깅한다면 이 정보는 의미가 없을 것입니다.

이 문서의 예는 매우 간단합니다. 발생한 후 다운타임이 발생하지 않았으므로 dmesg에서 전체 정보를 볼 수 있습니다. 그러나 이러한 오류 메시지는 파일에 저장될 시간이 없으며 전원을 끄면 더 이상 볼 수 없습니다. 손으로 쓰거나 사진을 찍는 등 다른 방법으로만 기록할 수 있습니다.

더 나쁜 상황이 있습니다. 정보가 너무 많으면 한 페이지의 화면이 완전히 표시되지 않습니다. 전체 내용을 어떻게 볼 수 있나요? 첫 번째 방법은 grub에서 vga 매개변수를 사용하여 화면에 더 많은 콘텐츠를 표시할 수 있도록 더 높은 해상도를 지정하는 것입니다. 분명히 이 방법은 너무 많은 문제를 해결할 수 없습니다. 두 번째 방법은 두 대의 시스템을 사용하여 직렬 포트를 통해 디버깅 시스템의 죄송합니다 정보를 호스트 화면에 인쇄하는 것입니다. 그러나 현재 대부분의 노트북에는 직렬 포트가 없으며 이 솔루션에도 큰 제한이 있습니다. 세 번째 방법은 오류가 발생할 때 커널 덤프 도구 kdump를 사용하여 파일에 메모리 및 CPU 레지스터의 내용을 덤프하는 것입니다. 문제를 분석하기 위해 gdb를 사용합니다.

커널 드라이버를 개발하는 과정에서 마주칠 수 있는 문제는 종류가 다양하고, 디버깅 방법도 다양합니다. 이런, 리눅스 커널이 우리에게 주는 알림인데 우리는 이를 잘 활용해야 합니다.

이 글을 통해 우리는 커널의 문제를 진단하고 디버그하는 데 사용할 수 있는 Linux 커널의 Oops의 원리와 특성에 대해 배웠습니다. 실제 요구 사항에 따라 적절한 도구를 선택하고 Oops 정보 저장 및 분석, 기호 테이블 및 소스 코드를 사용하여 문제 찾기, 모듈 매개 변수 및 커널 매개 변수를 사용하여 커널 동작 조정 등과 같은 몇 가지 기본 원칙을 따라야 합니다. 죄송합니다. Linux 커널의 일반적인 오류 메시지는 커널의 상태와 예외를 반영할 수 있으며 커널의 품질과 안정성을 향상시킬 수도 있습니다. 이 글이 여러분에게 도움이 되고 영감을 줄 수 있기를 바랍니다.

위 내용은 Linux 커널의 예외 정보: Oops에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Centos와 Ubuntu의 차이 Centos와 Ubuntu의 차이 Apr 14, 2025 pm 09:09 PM

Centos와 Ubuntu의 주요 차이점은 다음과 같습니다. Origin (Centos는 Red Hat, Enterprise의 경우, Ubuntu는 Debian에서 시작하여 개인의 경우), 패키지 관리 (Centos는 안정성에 중점을 둡니다. Ubuntu는 APT를 사용하여 APT를 사용합니다), 지원주기 (Ubuntu는 5 년 동안 LTS 지원을 제공합니다), 커뮤니티에 중점을 둔다 (Centos Conciors on ubuntu). 튜토리얼 및 문서), 사용 (Centos는 서버에 편향되어 있으며 Ubuntu는 서버 및 데스크탑에 적합), 다른 차이점에는 설치 단순성 (Centos는 얇음)이 포함됩니다.

Centos를 설치하는 방법 Centos를 설치하는 방법 Apr 14, 2025 pm 09:03 PM

CentOS 설치 단계 : ISO 이미지를 다운로드하고 부팅 가능한 미디어를 실행하십시오. 부팅하고 설치 소스를 선택하십시오. 언어 및 키보드 레이아웃을 선택하십시오. 네트워크 구성; 하드 디스크를 분할; 시스템 시계를 설정하십시오. 루트 사용자를 만듭니다. 소프트웨어 패키지를 선택하십시오. 설치를 시작하십시오. 설치가 완료된 후 하드 디스크에서 다시 시작하고 부팅하십시오.

Centos는 유지 보수를 중지합니다. 2024 Centos는 유지 보수를 중지합니다. 2024 Apr 14, 2025 pm 08:39 PM

Centos는 2024 년에 상류 분포 인 RHEL 8이 종료 되었기 때문에 폐쇄 될 것입니다. 이 종료는 CentOS 8 시스템에 영향을 미쳐 업데이트를 계속받지 못하게합니다. 사용자는 마이그레이션을 계획해야하며 시스템을 안전하고 안정적으로 유지하기 위해 Centos Stream, Almalinux 및 Rocky Linux가 포함됩니다.

Docker 원리에 대한 자세한 설명 Docker 원리에 대한 자세한 설명 Apr 14, 2025 pm 11:57 PM

Docker는 Linux 커널 기능을 사용하여 효율적이고 고립 된 응용 프로그램 실행 환경을 제공합니다. 작동 원리는 다음과 같습니다. 1. 거울은 읽기 전용 템플릿으로 사용되며, 여기에는 응용 프로그램을 실행하는 데 필요한 모든 것을 포함합니다. 2. Union 파일 시스템 (Unionfs)은 여러 파일 시스템을 스택하고 차이점 만 저장하고 공간을 절약하고 속도를 높입니다. 3. 데몬은 거울과 컨테이너를 관리하고 클라이언트는 상호 작용을 위해 사용합니다. 4. 네임 스페이스 및 CGroup은 컨테이너 격리 및 자원 제한을 구현합니다. 5. 다중 네트워크 모드는 컨테이너 상호 연결을 지원합니다. 이러한 핵심 개념을 이해 함으로써만 Docker를 더 잘 활용할 수 있습니다.

유지 보수를 중단 한 후 Centos의 선택 유지 보수를 중단 한 후 Centos의 선택 Apr 14, 2025 pm 08:51 PM

Centos는 중단되었으며 대안은 다음과 같습니다. 1. Rocky Linux (Best Compatibility); 2. Almalinux (Centos와 호환); 3. Ubuntu 서버 (구성 필수); 4. Red Hat Enterprise Linux (상업용 버전, 유료 라이센스); 5. Oracle Linux (Centos 및 Rhel과 호환). 마이그레이션시 고려 사항은 호환성, 가용성, 지원, 비용 및 커뮤니티 지원입니다.

Centos 후해야 할 일은 유지 보수를 중단합니다 Centos 후해야 할 일은 유지 보수를 중단합니다 Apr 14, 2025 pm 08:48 PM

Centos가 중단 된 후 사용자는 다음과 같은 조치를 취할 수 있습니다. Almalinux, Rocky Linux 및 Centos 스트림과 같은 호환되는 분포를 선택하십시오. Red Hat Enterprise Linux, Oracle Linux와 같은 상업 분포로 마이그레이션합니다. Centos 9 Stream : 롤링 분포로 업그레이드하여 최신 기술을 제공합니다. Ubuntu, Debian과 같은 다른 Linux 배포판을 선택하십시오. 컨테이너, 가상 머신 또는 클라우드 플랫폼과 같은 다른 옵션을 평가하십시오.

Docker Desktop을 사용하는 방법 Docker Desktop을 사용하는 방법 Apr 15, 2025 am 11:45 AM

Docker Desktop을 사용하는 방법? Docker Desktop은 로컬 머신에서 Docker 컨테이너를 실행하는 도구입니다. 사용 단계는 다음과 같습니다. 1. Docker Desktop 설치; 2. Docker Desktop을 시작하십시오. 3. Docker 이미지를 만듭니다 (Dockerfile 사용); 4. Docker Image 빌드 (Docker 빌드 사용); 5. 도커 컨테이너를 실행하십시오 (Docker Run 사용).

VSCODE에 필요한 컴퓨터 구성 VSCODE에 필요한 컴퓨터 구성 Apr 15, 2025 pm 09:48 PM

대 코드 시스템 요구 사항 : 운영 체제 : Windows 10 이상, MacOS 10.12 이상, Linux 배포 프로세서 : 최소 1.6GHz, 권장 2.0GHz 이상의 메모리 : 최소 512MB, 권장 4GB 이상의 저장 공간 : 최소 250MB, 권장 1GB 및 기타 요구 사항 : 안정 네트워크 연결, Xorg/Wayland (LINUX)

See all articles