記憶體區段錯誤

記憶體區段錯誤(英語:Segmentation fault,經常被縮寫為segfault),又譯為記憶體段错误,也稱存取權限衝突(access violation),是一種程式錯誤。

它會出現在當程式企圖存取CPU無法定址記憶體區段時。當錯誤發生時,硬體會通知作業系統產生了記憶體存取權限衝突的狀況。作業系統通常會產生核心轉儲(core dump)以方便程式員進行除錯。通常該錯誤是由于調用一個地址,而該地址為空(NULL)所造成的,例如鏈表中調用一個未分配地址的空鏈錶單元的元素。数组访问越界也可能产生这个错误。

概述

当程序试图访问不允许访问的内存位置,或试图以不允许的方式访问内存位置(例如,尝试写入只读位置,或覆盖操作系统的一部分)时,会产生储存器段错误。

术语“分段”在计算中有多种用途;“储存器段错误”是自1950年代以来就一直使用的术语。[1]当有内存保护时,只有程序自己的地址空间是可读的,其中只有堆栈和程序数据段的可读写部分是可写的,而只读数据和代码段是不可写的。因此,尝试读取程序地址空间之外的数据或写入至只读内存段时,会导致储存器段错误。

在使用硬件内存分段来提供虚拟内存的系统上,当硬件检测到尝试引用不存在的段、或引用段界限外的内存或引用无访问权限的内存段中的数据时,会发生储存器段错误。在仅使用内存分页的系统上,无效内存页错误通常会导致储存器段错误,而储存器段错误和内存页错误都是虚拟内存管理系统引发的错误。储存器段错误也可以独立于内存页错误发生:非法访问有效的内存页是会导致储存器段错误,而非无效内存页错误。并且段错误可能发生在内存页中间(因此没有内存页错误),例如处于同一内存页内但非法覆盖内存的缓冲区溢出。

在硬件级别,在非法访问时,如果引用的内存存在,错误最初由内存管理单元(MMU)抛出,作为其内存保护功能的一部分,或无效内存页错误(如果引用的内存不存在)。如果问题不是无效的逻辑地址而是无效的物理地址,则会引发总线错误,尽管并不总是能够区分这些错误。

在操作系统级别,这个错误会被捕获,并传递一个信号给有问题的进程,激活该进程的信号处理程序。不同的操作系统有不同的信号名称来表示发生了储存器段错误。在类Unix操作系统上,一个被称为SIGSEGV的信号被发送到该进程。在Microsoft Windows上,该进程会收到STATUS_ACCESS_VIOLATION异常。

错误原因

储存器段错误产生的条件和表现方式取决于硬件和操作系统:不同的硬件会在产生不一样的错误,且不同的操作系统会将这些错误转换成不同的信号发送给线程。 确定储存器段错误的根本原因在某些情况下十分容易(例如:访问空指针所指向的内存空间),程序会不断导致储存器段错误。在其他的一些情况,储存器段错误可能难以重现或者在意料不到的时候出现,这会让寻找储存器段错误的根本原因变得困难。

以下是一些导致储存器段错误的一般原因:

  • 试图访问不存在的内存空间(进程内存空间以外)
  • 试图访问没有权限的内存空间(例如:访问操作系统内核的内存地址)
  • 试图写入至只读内存段(例如:代码段)

以下是一些导致储存器段错误的一般编程错误:

  • 引用空指针
  • 引用未初始化的野指针
  • 引用已经被调用free()函数释放了的悬空指针
  • 缓冲区溢出
  • 堆栈溢出
  • 运行未正确编译的程序(尽管存在编译时错误,某些编译器依然会输出可执行文件)

在C代码中,由于容易错误地使用指针,储存器段错误最常发生。尤其是在C的动态内存分配中。 试图访问空指针所指向的内存区域总是会导致储存器段错误。而野指针和悬空指针则有时会导致储存器段错误,有时则不会。这是因为野指针和悬空指针所指向的内存可能存在也可能不存在,可能可写入也可能不可写入。这会导致储存器段错误会出现在意料不到的时候。

char *p1 = NULL;           // 空指针
char *p2;                  // 野指针:未被初始化的指针
char *p3  = malloc(10 * sizeof(char));  // 获取动态内存并初始化指针(假设malloc函数没有出错)
free(p3);                  // p3所指向的动态内存被释放掉,p3变成悬空指针

char c1 = *p1;             // 试图访问空指针所指向的内存总是会导致储存器段错误
char c2 = *p2;             // 试图访问野指针所指向的内存会导致随机数据
char c3 = *p3;             // 试图访问悬空指针所指向的内存可能会导致随机数据

试图访问这些指针中的任何一个所指向的内存都可能导致分段错误:试图访问空指针通常会导致储存器段错误;访问野指针所指向的内存可能会导致随机数据,因为指针未被初始化,指针所指向的内存地址是随机数;而访问悬空指针所指向的内存可能会在一定时间内访问到有效数据,但是当该数据被覆盖掉之后会导致随机数据。

处理储存器段错误

储存器段错误或总线错误的默认操作是异常终止触发该错误的进程。可能会生成核心文件以帮助调试,并且还可能执行依赖于其他平台的操作。例如,使用grsecurity补丁的Linux系统可能会记录SIGSEGV信号(当发生储存器段错误时,Linux系统会产生一个SIGSEGV信号,发生该错误的进程会捕获到该信号并异常终止该进程或者调用该进程与该信号绑定函数),以便监视可能使用缓冲区溢出来的非法入侵。

在某些系统上,例如Linux和Windows,程序本身可以处理储存器段错误。[2]根据体系结构和操作系统的不同,正在运行的程序不仅可以处理事件,还可以提取一些有关其状态的信息,例如获取堆栈跟踪、处理器寄存器值、触发时的源代码行、无效访问的内存地址,[3]以及该操作是读取还是写入。[4]

尽管储存器段错误通常意味着程序存在需要修复的错误,但也可能出于测试、调试以及模拟需要直接访问内存的平台的目的而故意导致此类故障。在后一种情况下,系统必须能够允许程序在发生故障后继续运行。在这种情况下,当系统允许时,可以处理该事件并增加处理器程序计数器以“跳过”错误的指令以继续执行。[5]

例子

写入至只读内存段

试图写入至只读内存段会引发储存器段错误。在代码错误的级别,当程序将数据写入至其代码段的或只读数据段时,就会发生储存器段错误。 以下是一个ANSI C代码示例,此段代码通常会在具有内存保护的平台上导致储存器段错误。它试图修改字符串文字,根据ANSI C标准,这是未定义的行为。大多数编译器不会在编译时捕获它,并将其编译成会崩溃的可执行代码:

int main(void){
    const char *s = "hello world\n";
    *s = 'H';
    printf("%s", s);
    return 0;
}

编译包含此代码的程序时,字符串“hello world”被放置在程序可执行文件的rodata部分:数据段的只读部分。加载该程序时,操作系统将它与其他字符串和常量数据一起放在内存的只读段中。执行时,指针s被设置为指向字符串的位置,并试图通过该指针将H字符写入至只读内存段,从而导致储存器段错误。使用编译时不检查只读位置分配的编译器来编译这样的程序,并在类Unix操作系统上运行会产生以下运行时错误:

$ gcc segfault.c -g -o segfault
$ ./segfault
储存器段错误

GDB产生的核心文件:

Program received signal SIGSEGV, Segmentation fault.
0x1c0005c2 in main () at segfault.c:6
6               *s = 'H';

可以使用字符数组来代替字符指针以更正代码,因为该字符串会储存在堆栈中,而非只读数据段中:

int main(void){
    char s[] = "hello world\n";
    *s = 'H';
    printf("%s", s);
    return 0;
}

编译并运行以上代码:

$ gcc no_segfault.c -g -o no_segfault
$ ./segfault
Hello world

尽管不应该修改字符串中的文字(这在C标准中具有未定义的行为),但在C中它们是static char []类型,[6][7][8]因此原始代码中没有隐性转换(指向该数组的字符指针),而在 C++ 中,它们是static const char []类型,存在隐性转换,因此编译器通常会捕获该错误。

试图访问空指针所指向的内存

在C和类C语言中,空指针用于表示“没有对象的指针”并作为错误指示符,而试图读取或写入空指针所指向的内存是非常常见的程序错误。C标准并没有指明空指针与指向内存地址0的指针相同,尽管在实践中可能是这种情况。大多数操作系统把空指针映射至会产生储存器段错误的内存。C标准不保证此行为。试图读取或写入空指针所指向的内存在C标准中是未定义的行为。

以下示例代码创建一个空指针,然后试图访问其值(读取该值)。运行这段代码会导致多数操作系统产生储存器段错误:

int *p_num = NULL;
printf("%d\n", *p_num);

以下示例代码创建一个空指针,并试图写入数据。运行这段代码会导致储存器段错误:

int *p_num = NULL;
*p_num = 1;

以下的代码包含一个空指针的解引用,但编译时通常不会导致储存器段错误,因为该值未被使用,因此该解引用通常会被当做死代码被消除掉以优化代码:

int *p_num = NULL;
*p_num;

缓冲区溢出

堆栈溢出

以下代码是一个没有出口的递归:

int main(void){
    main();
    return 0;
}

这会导致堆栈溢出,从而导致储存器段错误。[9]根据编程语言、编译器执行的优化和代码的确切结构,无限递归不一定会导致堆栈溢出。在这种情况下,无法访问代码(return 语句)的行为是未定义的,因此编译器可以消除它并且使用可能导致不用堆栈的尾调优化。其他优化可能包括将递归转换为迭代,鉴于示例函数的结构,程序将永远运行下去,同时大概率不会导致堆栈溢出。

参考资料

  1. ^ Debugging Segmentation Faults and Pointer Problems - Cprogramming.com. www.cprogramming.com. [2021-02-03]. (原始内容存档于2022-07-10). 
  2. ^ Cleanly recovering from Segfaults under Windows and Linux (32-bit, x86). [2020-08-23]. (原始内容存档于2021-09-13). 
  3. ^ Implementation of the SIGSEGV/SIGABRT handler which prints the debug stack trace.. [2020-08-23]. (原始内容存档于2021-09-13). 
  4. ^ How to identify read or write operations of page fault when using sigaction handler on SIGSEGV?(LINUX). [2020-08-23]. (原始内容存档于2021-09-13). 
  5. ^ LINUX – WRITING FAULT HANDLERS. [2020-08-23]. (原始内容存档于2021-09-13). 
  6. ^ 6.1.4 String literals. ISO/IEC 9899:1990 - Programming languages -- C. 
  7. ^ 6.4.5 String literals. ISO/IEC 9899:1999 - Programming languages -- C. 
  8. ^ 6.4.5 String literals. ISO/IEC 9899:2011 - Programming languages -- C. [2021-09-13]. (原始内容存档于2022-04-21). 
  9. ^ What is the difference between a segmentation fault and a stack overflow?页面存档备份,存于互联网档案馆) at Stack Overflow

Read other articles:

Ikan tamban Status konservasi Risiko Rendah (IUCN 3.1) Klasifikasi ilmiah Domain: Eukaryota Kerajaan: Animalia Filum: Chordata Kelas: Actinopterygii Ordo: Clupeiformes Subordo: Clupeoidei Famili: Spratelloididae Genus: Spratelloides Spesies: Spratelloides gracilis(Temminck & Schlegel, 1846) Ikan tamban atau ikan Kibinago ( Spratelloides gracilis ) adalah ikan mangsa kecil mirip herring . Mereka adalah ikan-ikan kecil yang digunakan sebagai umpan mancing, khususnya dalam mancing caka...

 

 

Charles Antoine MorandComte KekaisaranLahir4 Juni 1771Pontarlier, DoubsMeninggal2 Desember 1835ParisDikebumikanPemakaman Père-LachaisePengabdian PrancisDinas/cabangInfanteriLama dinas1792–1815PangkatDivisi JenderalPerang/pertempuranPerang Revolusi PrancisPeperangan era NapoleonPenghargaanKomandan Agung Légion d'honneurSalib Agung Ordo ReunionKomandan Ordo Militer St. HeinrichKnight St. LouisPairie de France Charles-Antoine-Louis-Alexis Morand (4 Juni 1771 – 2 Desember 1835)[1&#...

 

 

New York City Subway station in Queens New York City Subway station in Queens, New York 67 Avenue ​ New York City Subway station (rapid transit)R160 R train departing from the northbound platformStation statisticsAddress67th Avenue & Queens BoulevardForest Hills, NY 11375BoroughQueensLocaleForest HillsCoordinates40°43′37″N 73°51′13″W / 40.726966°N 73.853703°W / 40.726966; -73.853703DivisionB (IND)[1]LineIND Queens Boulevard Line...

India-related events during the year of 1935 This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: 1935 in India – news · newspapers · books · scholar · JSTOR (December 2013) (Learn how and when to remove this message) ← 1934 1933 1932 1935 in India → 1936 1937 1938 Centuries: 18th 19th 20th 21st Decad...

 

 

Indian Bhojpuri Entertainment Channel This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages) This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Dishum TV – news · newspapers · books · scholar · JSTOR (May 2018) (L...

 

 

Montney FormationStratigraphic range: Anisian PreꞒ Ꞓ O S D C P T J K Pg N TypeGeological formationUnderliesDoig Formation, Fernie GroupOverliesBelloy FormationArea130,000 square kilometres (50,190 sq mi)[1]Thicknessup to 280 metres (920 ft)[2]LithologyPrimarySiltstone and shaleOtherDolomitic siltstone, sandstoneLocationCoordinates56°34′18″N 121°13′19″W / 56.57159°N 121.2219°W / 56.57159; -121.2219 (Buick Creek No. ...

Town in Odisha, IndiaKhallikoteTownKhallikoteLocation in OdishaShow map of OdishaKhallikoteLocation in IndiaShow map of IndiaCoordinates: 19°37′N 85°05′E / 19.62°N 85.08°E / 19.62; 85.08Country IndiaState OdishaDistrictGanjamElevation54 m (177 ft)Population (2011) • Total13,022 [1]Languages • OfficialOdiaTime zoneUTC+5:30 (IST)PIN761030Telephone code06810Vehicle registrationOR-07/OD-07 Khallikote is a town an...

 

 

Igor SikorskyFoto Igor, c. 1950LahirIgor Ivanovich Sikorsky(1889-05-25)25 Mei 1889Kiev, Russian Empire (saat ini Ukraine)Meninggal26 Oktober 1972(1972-10-26) (umur 83)Easton, Connecticut, USA Igor Ivanovich Sikorsky (bahasa Rusia: Игорь Иванович Сикорский,; 25 Mei 1889 - 26 Oktober 1972), adalah seorang perintis pembuatan helikopter dan pesawat bersayap keturunan Rusia-Amerika.[1] Dia merancang dan pesawat bersayap multi-mesin pertama di dunia, Russky Vitya...

 

 

Private performing arts conservatory Not to be confused with the former name of a performing arts institute in Sydney with the same acronym – the Australian Academy of Dramatic Art. American Academy of Dramatic ArtsTypePrivate drama schoolEstablished1884FounderFranklin Haven SargentEndowmentApprox. $5 millionPresidentSusan Zech (born 1971)[i]Academic staffNew York total: 39[1](31 of 39 part time) Los Angeles total: 50[1] (41 of 50 part-time)Administrative staffNew Yo...

تحتاج هذه المقالة إلى الاستشهاد بمصادر إضافية لتحسين وثوقيتها. فضلاً ساهم في تطوير هذه المقالة بإضافة استشهادات من مصادر موثوق بها. من الممكن التشكيك بالمعلومات غير المنسوبة إلى مصدر وإزالتها. الغزو الفرنسي للمغرب جزء من تاريخ المغرب   التاريخ وسيط property غير متوفر. بداية...

 

 

Arbenan Klasifikasi ilmiah Domain: Eukaryota Kerajaan: Plantae (tanpa takson): Tracheophyta (tanpa takson): Angiospermae (tanpa takson): Eudikotil (tanpa takson): Rosid Ordo: Rosales Famili: Rosaceae Subfamili: Rosoideae Tribus: Potentilleae Genus: Potentilla Spesies: Potentilla indica(Andrews) Th.Wolf Sinonim[1] Duchesnea indica (Andrews) Teschem. Duchesnea major (Makino) Makino Fragaria indica Andrews Fragaria malayana Roxb. Fragaria nilagirica Zenker Potentilla denticulosa Ser. Po...

 

 

Fosse no 3 des mines de Ligny-lès-Aire La fosse no 3. Puits n° 3 Coordonnées 50,556703, 2,357589[BRGM 1] Début du fonçage 1er avril 1927 Mise en service mai 1929 Profondeur 483 mètres Arrêt 1950 Remblaiement ou serrement 1950 Administration Pays France Région Hauts-de-France Département Pas-de-Calais Commune Auchy-au-Bois Caractéristiques Compagnie Compagnie des mines de Ligny-lès-Aire Groupe Groupe d'Auchel Ressources Houille Concession Auchy-au-Bois Protection ...

Local authority in Northern Ireland Antrim and Newtownabbey Borough CouncilTypeTypeDistrict council of Antrim and NewtownabbeyHistoryFounded1 April 2015Preceded byAntrim Borough CouncilNewtownabbey Borough CouncilLeadershipMayorCouncillor Mark Cooper, Democratic Unionist Party Deputy MayorCouncillor Rosie Kinnear, Sinn Féin StructureSeats40Political groupsExecutive (20)  DUP (13)  UUP (6)Opposition (20)  Sinn Féin (9)   Alliance (8)  Independent (3) ...

 

 

Ethnic group in the Philippines This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Igorot people – news · newspapers · books · scholar · JSTOR (July 2021) (Learn how and when to remove this message) Ethnic group IgorotElderly Igorots in traditional attireTotal population1,854,556[1]Regions with signific...

 

 

State park in Washington (state), United States Lincoln Rock State ParkLincoln Rock across Lake EntiatLocation in the state of WashingtonShow map of Washington (state)Lincoln Rock State Park (the United States)Show map of the United StatesLocationDouglas, Washington, United StatesCoordinates47°32′09″N 120°17′01″W / 47.53583°N 120.28361°W / 47.53583; -120.28361Area86 acres (35 ha)Established1981OperatorWashington State Parks and Recreation CommissionWeb...

Enzyme ATP SynthaseMolecular model of ATP synthase determined by X-ray crystallography. Stator is not shown here.IdentifiersEC no.7.1.2.2CAS no.9000-83-3 DatabasesIntEnzIntEnz viewBRENDABRENDA entryExPASyNiceZyme viewKEGGKEGG entryMetaCycmetabolic pathwayPRIAMprofilePDB structuresRCSB PDB PDBe PDBsumGene OntologyAmiGO / QuickGOSearchPMCarticlesPubMedarticlesNCBIproteins ATP synthase is an enzyme that catalyzes the formation of the energy storage molecule adenosine triphosphate (ATP) using ade...

 

 

هذه المقالة تحتاج للمزيد من الوصلات للمقالات الأخرى للمساعدة في ترابط مقالات الموسوعة. فضلًا ساعد في تحسين هذه المقالة بإضافة وصلات إلى المقالات المتعلقة بها الموجودة في النص الحالي. (يوليو 2019) منتخب إيطاليا لهوكي الدحرجة للسيدات اللقب Hockey rosa البلد إيطاليا  تعديل مصدري ...

 

 

Second largest lake in Sweden VätternWest to east view of the lake including Visingsö in the foregroundVätternCoordinates58°24′N 14°36′E / 58.400°N 14.600°E / 58.400; 14.600Primary outflowsMotala strömCatchment area4,503 km2 (1,739 sq mi)Basin countriesSwedenSurface area1,912 km2 (738 sq mi)[1]Average depth41 m (135 ft)[1]Max. depth128 m (420 ft)[1]Water volume77.0 km3 (18.5...

Defunct airline of Thailand (2005–2009) This article has multiple issues. Please help improve it or discuss these issues on the talk page. (Learn how and when to remove these template messages) The topic of this article may not meet Wikipedia's notability guidelines for companies and organizations. Please help to demonstrate the notability of the topic by citing reliable secondary sources that are independent of the topic and provide significant coverage of it beyond a mere trivial mention....

 

 

宋哲元 第6任河北省政府主席任期1935年12月12日—1936年11月27日 前任商震继任孫連仲 第4任察哈爾省政府主席任期1932年8月18日—1935年6月19日 前任劉翼飛继任秦德純 个人资料性别男出生1885年10月30日 清朝山東省樂陵縣逝世1940年4月5日(1940歲—04—05)(54歲) 中華民國四川省綿陽縣政党 中國國民黨军事背景效忠 中華民國服役 國民革命軍军衔 一級上將(追晉) 学�...