Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«ΠžΡΠ½ΠΎΠ²Ρ‹ программирования Π² LinuxΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 116

Автор НСйл ΠœΡΡ‚ΡŒΡŽ

ΠžΠ±Ρ‰ΠΈΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΡ‚Π»Π°Π΄ΠΊΠΈ

БущСствуСт нСсколько Ρ€Π°Π·Π½Ρ‹Ρ… ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠ² ΠΊ ΠΎΡ‚Π»Π°Π΄ΠΊΠ΅ ΠΈ Ρ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡŽ Ρ‚ΠΈΠΏΠΎΠ²ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Linux. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ запускаСт ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ смотрит, Ρ‡Ρ‚ΠΎ происходит. Если ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Ρ€Π΅ΡˆΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ с Π½Π΅ΠΉ Π΄Π΅Π»Π°Ρ‚ΡŒ. МоТно ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ ΠΏΠΎΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ снова (Π°Π½Π°Π»ΠΈΠ· ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°, ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΏΡ€ΠΎΠ± ΠΈ ошибок), ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΏΡ‹Ρ‚Π°Ρ‚ΡŒΡΡ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ большС ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ происходит Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (оснащСниС ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½Ρ‹ΠΌΠΈ срСдствами) ΠΈΠ»ΠΈ ΠΌΠΎΠΆΠ½ΠΎ нСпосрСдствСнно ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ (ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅). ΠžΡ‚Π»Π°Π΄ΠΊΠ° Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя ΠΏΡΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… этапов:

β–‘ Ρ‚СстированиС β€” поиск ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… изъянов ΠΈΠ»ΠΈ ошибок;

β–‘ ΡΡ‚абилизация β€” обСспСчСниС повторяСмости ошибок;

β–‘ Π»ΠΎΠΊΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ β€” ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ строки ΠΊΠΎΠ΄Π°, ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‰Π΅ΠΉ Π·Π° ΠΎΡˆΠΈΠ±ΠΊΡƒ;

β–‘ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° β€” исправлСниС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°;

β–‘ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° β€” ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ исправлСниС Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° с ошибками

Π”Π°Π²Π°ΠΉΡ‚Π΅ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, содСрТащСй ошибки. Читая Π΄Π°Π½Π½ΡƒΡŽ Π³Π»Π°Π²Ρƒ, Π²Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚Π΅ ΠΏΡ€ΠΎΠ±ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚Π»Π°Π΄ΠΈΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ. Она написана Π²ΠΎ врСмя Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ большой ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΉ систСмы. Π•Π΅ Π·Π°Π΄Π°Ρ‡Π° β€” ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π΄ΠΈΠ½ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sort, которая ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ сортировки массива структур Ρ‚ΠΈΠΏΠ° item ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ "ΠΏΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ°". Π­Π»Π΅ΠΌΠ΅Π½Ρ‚Ρ‹ ΡΠΎΡ€Ρ‚ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ Π²ΠΎΠ·Ρ€Π°ΡΡ‚Π°Π½ΠΈΡŽ поля key. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sort для сортировки ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€ΠΎΡ‚Π΅ΡΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. Π’ Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΉ ΠΆΠΈΠ·Π½ΠΈ Π²Ρ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ стали Π±Ρ‹ ΠΎΠ±Ρ€Π°Ρ‰Π°Ρ‚ΡŒΡΡ ΠΊ этому ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ ΠΈΠ·-Π·Π° Π΅Π³ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π½ΠΈΠ·ΠΊΠΎΠΉ эффСктивности. ΠœΡ‹ ΠΆΠ΅ примСняСм Π΅Π³ΠΎ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ, ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ простой ΠΈ Π΅Π³ΠΎ Π»Π΅Π³ΠΊΠΎ ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π² Π½Π΅ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ. На самом Π΄Π΅Π»Π΅ Π² стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ языка Π‘ Π΅ΡΡ‚ΡŒ функция с ΠΈΠΌΠ΅Π½Π΅ΠΌ qsort, Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‰Π°Ρ эту Π·Π°Π΄Π°Ρ‡Ρƒ.

К соТалСнию, исходный ΠΊΠΎΠ΄ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π½Π΅Π»Π΅Π³ΠΊΠΎ читаСтся, Π² Π½Π΅ΠΌ Π½Π΅Ρ‚ ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠ΅Π², ΠΈ Π°Π²Ρ‚ΠΎΡ€ ΡƒΠΆΠ΅ нСдоступСн. Π’Π°ΠΌ придСтся Π±ΠΈΡ‚ΡŒΡΡ с Π½Π΅ΠΉ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ, начиная с основной ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ debug1.c.

/*  1 */ typedef struct {

/*  2 */  char *data;

/*  3 */  int key;

/*  4 */ } item;

/*  5 */

/*  6 */ item array[] = {

/*  7 */  {"bill", 3},

/*  8 */  {"neil", 4},

/*  9 */  {"john", 2},

/* 10 */  {"rick", 5},

/* 11 */  {"alex", 1},

/* 12 */ };

/* 13 */

/* 14 */ sort(a, n)

/* 15 */ item *a;

/* 16 */ {

/* 17 */  int i = 0, j = 0;

/* 18 */  int s = 1;

/* 19 */

/* 20 */  for(; i < n && s != 0; i++) {

/* 21 */   s = 0;

/* 22 */   for(j = 0; j < n; j++) {

/* 23 */    if(a[j].key > a[j + 1].key) {

/* 24 */     item t = a[j];

/* 25 */     a[j] = a[j+1];

/* 26 */     a[j+1] = t;

/* 27 */     s++;

/* 28 */    }

/* 29 */   }

/* 30 */   n--;

/* 31 */  }

/* 32 */ }

/* 33 */

/* 34 */ main()

/* 35 */ {

/* 36 */  sort(array,5);

/* 37 */ }

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠΎΠΏΡ‹Ρ‚Π°ΠΉΡ‚Π΅ΡΡŒ ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ:

$ сс -о debug1 debug1.с

Она компилируСтся ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π±Π΅Π· ΠΊΠ°ΠΊΠΈΡ…-Π»ΠΈΠ±ΠΎ сообщСний ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… ΠΈΠ»ΠΈ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ.

ΠŸΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ эту ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Π²ΡΡ‚Π°Π²ΡŒΡ‚Π΅ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚ ΠΊΠΎΠ΄Π° для Π²Ρ‹Π²ΠΎΠ΄Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС Π²Ρ‹ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚Π΅ Π·Π½Π°Ρ‚ΡŒ, ΠΎΡ‚Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° Π»ΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°. Π’Ρ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚Π΅ нСсколько Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… строк для отобраТСния массива послС сортировки. НазовитС Π½ΠΎΠ²ΡƒΡŽ Π²Π΅Ρ€ΡΠΈΡŽ debug2.c.

/* 33 */ #include <stdio.h>

/* 34 */ main()

/* 35 */ {

/* 36 */  int i;

/* 37 */  sort(array, 5);

/* 38 */  for(i = 0; i < 5; i++)

/* 39 */   printf("array[3d] = (%s, %d)\n",

/* 40 */    i, array[i].data, array[i].key);

/* 41 */ }

Π­Ρ‚ΠΎΡ‚ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄, строго говоря, Π½Π΅ являСтся Ρ‡Π°ΡΡ‚ΡŒΡŽ, ΠΏΠΎΠ·ΠΆΠ΅ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Π½ΠΎΠΉ программистом. ΠœΡ‹ заставили вас Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для тСстирования ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘Π»Π΅Π΄ΡƒΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ Π²Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ внСсти Π½ΠΎΠ²Ρ‹Ρ… ошибок Π² ваш тСстовый ΠΊΠΎΠ΄. Π’Π΅ΠΏΠ΅Ρ€ΡŒ снова ΠΎΡ‚ΠΊΠΎΠΌΠΏΠΈΠ»ΠΈΡ€ΡƒΠΉΡ‚Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ ΠΈ Π½Π° этот Ρ€Π°Π· Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅ Π΅Π΅:

$ cc -о debug2 debug2.с

$ ./debug2

Π§Ρ‚ΠΎ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ сдСлаСтС это, зависит ΠΎΡ‚ вашСй вСрсии Linux (ΠΈΠ»ΠΈ UNIX) ΠΈ особСнностСй Π΅Π΅ установки. Π’ своих систСмах ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

array[0] = {john, 2}

array[1] = {alex, 1}

array[2] = {(null), -1}

array[3] = {bill, 3}

array[4] = {neil, 4}

Π’ Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎΠΉ систСмС (Π·Π°ΠΏΡƒΡΠΊΠ°ΡŽΡ‰Π΅ΠΉ Π΄Ρ€ΡƒΠ³ΠΎΠ΅ ядро Linux) ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π²ΠΎΠ΄:

Segmentation fault

Π’ вашСй систСмС Linux Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹Ρ… Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² ΠΈΠ»ΠΈ совсСм Π΄Ρ€ΡƒΠ³ΠΎΠΉ. ΠœΡ‹ рассчитывали ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ Π΄Π°Π»Π΅Π΅ Π²Ρ‹Π²ΠΎΠ΄:

array[0] = {alex, 1}

array[1] = {john, 2}

array[2] = {bill, 3}

array[3] = {neil, 4}

array[4] = {rick, 5}

Ясно, Ρ‡Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ Π΅ΡΡ‚ΡŒ ΡΠ΅Ρ€ΡŒΠ΅Π·Π½Π°Ρ ошибка. Он Π½Π΅ выполняСт сортировку ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ, Ссли Π²ΠΎΠΎΠ±Ρ‰Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, Π° Ссли ΠΎΠ½ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ с ошибкой сСгмСнтации, Ρ‚ΠΎ опСрационная систСма посылаСт сигнал ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, сообщая ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ нСсанкционированный доступ ΠΊ памяти, ΠΈ ΠΏΡ€Π΅ΠΆΠ΄Π΅Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΈΡΠΏΠΎΡ€Ρ‚ΠΈΡ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ памяти.

Π‘ΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠΈΡ‚ΡŒ нСсанкционированный доступ ΠΊ памяти зависит ΠΎΡ‚ настройки оборудования ΠΈ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… тонкостСй Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ систСмы управлСния ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ. Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ систСм объСм памяти, выдСляСмый ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмой, большС Ρ€Π΅Π°Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠΎΠ³ΠΎ. Если нСсанкционированный доступ осущСствляСтся ΠΊ этому участку памяти, ΠΎΠ±ΠΎΡ€ΡƒΠ΄ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π΅ Π²Ρ‹ΡΠ²ΠΈΡ‚ΡŒ нСсанкционированный доступ. Π’ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π½Π΅ всС вСрсии Linux ΠΈ UNIX ΡΠ³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‚ сигнал ΠΎ Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠΈ сСгмСнтации.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

НСкоторыС Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅Ρ‡Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ printf, Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹Ρ… ΠΎΠ±ΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΡΡ‚Π²Π°Ρ… Ρ‚Π°ΠΊΠΆΠ΅ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΡ€Π΅ΠΏΡΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΌΡƒ доступу, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΡ€ΠΈ использовании указатСля null.

Когда Π²Ρ‹ исслСдуСтС ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ доступа ΠΊ элСмСнтам массива, часто ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ этих элСмСнтов, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ это ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ ошибки. Если Π²Ρ‹ Ρ‡ΠΈΡ‚Π°Π΅Ρ‚Π΅ СдинствСнный Π±Π°ΠΉΡ‚ Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ массива Π±Π°ΠΉΡ‚ΠΎΠ², это ΠΌΠΎΠΆΠ΅Ρ‚ Π²Π°ΠΌ сойти с Ρ€ΡƒΠΊ, Ρ‚.ΠΊ. ΠΏΠ°ΠΌΡΡ‚ΡŒ, выдСлСнная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠΊΡ€ΡƒΠ³Π»ΡΡ‚ΡŒΡΡ Π΄ΠΎ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρ‹, зависящСй ΠΎΡ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмы, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ€Π°Π²Π½ΠΎΠΉ 8 ΠšΠ±Π°ΠΉΡ‚.

Если Π²Ρ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€ элСмСнта массива, Π·Π°ΠΌΠ΅Π½ΠΈΠ² элСмСнт Ρ‚ΠΈΠΏΠ° item массивом ΠΈΠ· 4096 символов, любоС ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌΡƒ элСмСнту массива, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, окаТСтся Π·Π° ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ Π²Ρ‹Π΄Π΅Π»Π΅Π½Π½ΠΎΠΉ памяти. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ элСмСнт массива Ρ€Π°Π²Π΅Π½ 4 ΠšΠ±Π°ΠΉΡ‚, поэтому Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹ΠΉ участок памяти Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒΡΡ Π·Π° ΠΊΠΎΠ½Ρ†ΠΎΠΌ массива Π½Π° расстоянии ΠΎΡ‚ 0 Π΄ΠΎ 4 ΠšΠ±Π°ΠΉΡ‚.

Если ΠΌΡ‹ внСсСм эту ΠΏΠΎΠΏΡ€Π°Π²ΠΊΡƒ, Π½Π°Π·Π²Π°Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ debug3.c, Ρ‚ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ ΠΎΡˆΠΈΠ±ΠΊΡƒ сСгмСнтации Π² вСрсиях Linux ΠΎΠ±ΠΎΠΈΡ… Π°Π²Ρ‚ΠΎΡ€ΠΎΠ².

/* 2 */ char data[4096];


$ сс -о debug3 debug3.с

$ ./debug3

Segmentation fault

Π’ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ систСм Linux ΠΈΠ»ΠΈ UNIX всС Π΅Ρ‰Π΅ Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π΄Π°Π²Π°Ρ‚ΡŒ сообщСниС ΠΎΠ± ошибкС сСгмСнтации. Когда стандарт ANSI Π‘ ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ, Π½Π° самом Π΄Π΅Π»Π΅ ΠΎΠ½ Ρ€Π°Π·Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π΄Π΅Π»Π°Ρ‚ΡŒ всС, Ρ‡Ρ‚ΠΎ ΡƒΠ³ΠΎΠ΄Π½ΠΎ. Π­Ρ‚ΠΎ выглядит Ρ‚Π°ΠΊ, ΠΊΠ°ΠΊ Π±ΡƒΠ΄Ρ‚ΠΎ ΠΌΡ‹ написали Π½Π΅ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΡƒΡŽ стандартам ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ Π½Π° языкС Π‘, ΠΈ ΠΎΠ½Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ странноС ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅! Как Π²ΠΈΠ΄ΠΈΡ‚Π΅, изъян Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄ΠΈΡ‚ Π΅Π΅ Π² ΠΊΠ°Ρ‚Π΅Π³ΠΎΡ€ΠΈΡŽ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌ с нСпрСдсказуСмым ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ.

Анализ кода

Как ΠΌΡ‹ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΈ Ρ€Π°Π½Π΅Π΅, часто, Ссли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚, ΠΊΠ°ΠΊ оТидалось, Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΅Π΅. ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΌΡ‹ просмотрСли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° этой Π³Π»Π°Π²Ρ‹ ΠΈ исправили Π² Π½Π΅ΠΌ всС ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹Π΅ ошибки.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Анализ ΠΊΠΎΠ΄Π° β€” это Ρ‚Π΅Ρ€ΠΌΠΈΠ½, примСняСмый для обозначСния Π±ΠΎΠ»Π΅Π΅ Ρ„ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ процСсса, Π² Ρ…ΠΎΠ΄Π΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π³Ρ€ΡƒΠΏΠΏΠ° Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ просматриваСт нСсколько сотСн строк ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°, Π½ΠΎ ΠΌΠ°ΡΡˆΡ‚Π°Π± Π½Π΅ ΠΈΠΌΠ΅Π΅Ρ‚ значСния, это всС Ρ€Π°Π²Π½ΠΎ Π°Π½Π°Π»ΠΈΠ· ΠΊΠΎΠ΄Π°, ΠΈ ΠΎΠ½ остаСтся ΠΎΡ‡Π΅Π½ΡŒ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ поиска ошибок.

Π‘ΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‚ срСдства, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠΌΠΎΡ‡ΡŒ Π² Π°Π½Π°Π»ΠΈΠ·Π΅ ΠΊΠΎΠ΄Π°, ΠΎΠ΄Π½ΠΎ ΠΈΠ· самых ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹Ρ… β€” компилятор. Он сообщит Π²Π°ΠΌ ΠΎ Π»ΡŽΠ±Ρ‹Ρ… ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΡ…ΡΡ Π² вашСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ синтаксичСских ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ….

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Π£ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… компиляторов Π΅ΡΡ‚ΡŒ ΠΎΠΏΡ†ΠΈΠΈ, Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‰ΠΈΠ΅ прСдупрСТдСния Π² ΡΠΎΠΌΠ½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… случаях, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ отсутствиС ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΈΠ»ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ присваиваний Π² условиях. НапримСр, компилятор GNU ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌΠΈ опциями:

gcc -Wall -pedantic -ansi

Они ΠΏΠΎΡ€ΠΎΠΆΠ΄Π°ΡŽΡ‚ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΡ€Π΅Π΄ΡƒΠΏΡ€Π΅ΠΆΠ΄Π΅Π½ΠΈΠΉ ΠΈ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΎΠΊ Π½Π° соотвСтствиС стандартам языка Π‘. Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ Π²Π·ΡΡ‚ΡŒ Π·Π° ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ использованиС этих ΠΎΠΏΡ†ΠΈΠΉ, особСнно Wall. Она Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΏΠΎΠ»Π΅Π·Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ ΠΏΡ€ΠΈ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠΈ ошибок Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅.

Π§ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅ ΠΌΡ‹ ΠΊΡ€Π°Ρ‚ΠΊΠΎ обсудим ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ срСдства, lint ΠΈ splint. Как ΠΈ компилятор, ΠΎΠ½ΠΈ Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΡŽΡ‚ ΠΊΠΎΠ΄ ΠΈ ΡΠΎΠΎΠ±Ρ‰Π°ΡŽΡ‚ ΠΎ Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π°Ρ… ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΌΠΈ.