Falla de segmentació

De la Viquipèdia, l'enciclopèdia lliure
Error de segmentació que afecta Krita a l'entorn d'escriptori KDE

En informàtica, una falla de segmentació (sovint escurçada a error de seg) o una infracció d'accés és una fallada o una condició de fallada generada pel maquinari amb protecció de memòria, que notifica a un sistema operatiu (SO) que el programari ha intentat accedir a una àrea restringida de memòria (un violació d'accés a la memòria). En ordinadors x86 estàndard, aquesta és una forma d' error de protecció general. El nucli del sistema operatiu, com a resposta, sol dur a terme alguna acció correctiva, generalment transmetent l'error al procés ofensiu enviant al procés un senyal. En alguns casos, els processos poden instal·lar un gestor de senyals personalitzat, que els permet recuperar-se per si mateixos, però, en cas contrari, s'utilitza el gestor de senyals predeterminat del sistema operatiu, que generalment provoca una terminació anormal del procés (un error del programa) i, de vegades, un abocament de nucli.

Error de segmentació al lector de targetes de dèbit/crèdit.

Els errors de segmentació són una classe d'error habitual en programes escrits en llenguatges com C que proporcionen accés a memòria de baix nivell i poques comprovacions de seguretat. Sorgeixen principalment a causa d'errors en l'ús dels punters per a l'adreçament de la memòria virtual, especialment l'accés il·legal. Un altre tipus d'error d'accés a la memòria és un error de bus, que també té diverses causes, però avui és molt més rar; aquests es produeixen principalment a causa d'un adreçament incorrecte de la memòria física o a causa d'un accés a la memòria desalineat: són referències de memòria que el maquinari no pot abordar, en lloc de referències que un procés no pot abordar.

Molts llenguatges de programació poden emprar mecanismes dissenyats per evitar errors de segmentació i millorar la seguretat de la memòria. Per exemple, Rust utilitza un model [1] basat en la propietat per garantir la seguretat de la memòria.[2] Altres llenguatges, com Lisp i Java, utilitzen la recollida d'escombraries,[3] que evita certes classes d'errors de memòria que podrien provocar errors de segmentació.

Visió general[modifica]

Un error de segmentació es produeix quan un programa intenta accedir a una ubicació de memòria a la qual no està permès accedir, o intenta accedir a una ubicació de memòria d'una manera que no està permesa (per exemple, intentant escriure en una ubicació de només lectura, o per sobreescriure part del sistema operatiu).

El terme "segmentació" té diversos usos en informàtica; en el context de "falla de segmentació", terme utilitzat des de la dècada de 1950, fa referència a l'espai d'adreces d'un programa. [4] Amb la protecció de memòria, només es pot llegir l'espai d'adreces del programa i, d'això, només es poden escriure la pila i la part de lectura/escriptura del segment de dades d'un programa, mentre que les dades de només lectura i el segment de codi no es poden escriure. Així, intentar llegir fora de l'espai d'adreces del programa, o escriure en un segment de només lectura de l'espai d'adreces, provoca un error de segmentació, d'aquí el nom.

Causes[modifica]

Les condicions en què es produeixen les infraccions de segmentació i com es manifesten són específiques del maquinari i del sistema operatiu: un maquinari diferent provoca diferents errors per a condicions determinades i diferents sistemes operatius els converteixen en senyals diferents que es transmeten als processos. La causa propera és una violació d'accés a la memòria, mentre que la causa subjacent és generalment un error de programari d'algun tipus. Determinar la causa arrel (depurar l'error) pot ser senzill en alguns casos, on el programa causarà constantment un error de segmentació (per exemple, desreferenciant un punter nul), mentre que en altres casos l'error pot ser difícil de reproduir i dependrà de l'assignació de memòria. a cada tirada (p. ex., desreferenciar un punter penjant).

Les següents són algunes de les causes típiques d'una falla de segmentació:

  • S'està intentant accedir a una adreça de memòria inexistent (fora de l'espai d'adreces del procés)
  • Intentar accedir a la memòria del programa no té drets (com ara les estructures del nucli en el context del procés)
  • S'està intentant escriure memòria de només lectura (com ara un segment de codi)

Aquests, al seu torn, sovint són causats per errors de programació que donen lloc a un accés a la memòria no vàlid:

  • Desreferenciar un punter nul, que normalment apunta a una adreça que no forma part de l'espai d'adreces del procés.
  • Desreferenciació o assignació a un punter no inicialitzat (punter salvatge, que apunta a una adreça de memòria aleatòria).
  • Desreferenciació o assignació a un punter alliberat (punter penjant, que apunta a la memòria que s'ha alliberat/desassignat/suprimit).
  • Un desbordament del buffer.
  • Un desbordament de pila.
  • S'està intentant executar un programa que no es compila correctament. (Alguns compiladors generaran un fitxer executable malgrat la presència d'errors en temps de compilació).

Referències[modifica]

  1. «The Rust Programming Language - Ownership» (en anglès).
  2. «Fearless Concurrency with Rust - The Rust Programming Language Blog» (en anglès).
  3. McCarthy, John Communications of the ACM, 4, 3, abril 1960, pàg. 184–195. DOI: 10.1145/367177.367199 [Consulta: 22 setembre 2018].
  4. «Debugging Segmentation Faults and Pointer Problems - Cprogramming.com» (en anglès). www.cprogramming.com. [Consulta: 3 febrer 2021].