Shell Script - Ошибка сегментации - PullRequest
1 голос
/ 20 декабря 2011

Я столкнулся с небольшим тупиком, пытаясь заставить работать сценарий оболочки.Я пытаюсь создать сценарий, который читает строку из базы данных и форматирует ее в текстовый файл для использования с другим программным обеспечением.Сценарий должен зацикливаться около 50 миллионов раз (большая база данных), и он прекрасно работает до 5500–5800 итераций, после чего возникает ошибка сегментации.
Я пытался отследить ошибку с помощью strace (Последние несколькостроки ниже), но я не совсем уверен, что я смотрю.

clone(child_stack=0,flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,                      child_tidptr=0xb76f8728) = 17547
close(4)                                = 0
close(5)                                = 0
pipe([4, 5])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,     child_tidptr=0xb76f8728) = 17548
close(3)                                = 0
close(5)                                = 0
pipe([3, 5])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17549
close(4)                                = 0
close(5)                                = 0
pipe([4, 5])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17550
close(3)                                = 0
close(5)                                = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17551
close(4)                                = 0
close(-1)                               = -1 EBADF (Bad file descriptor)
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17546
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17547
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17548
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17549
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17551
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17550
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17545
--- SIGCHLD (Child exited) @ 0 (0) ---
write(1, "OK!\n", 4OK!
)                    = 4
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,   child_tidptr=0xb76f8728) = 17552
close(4)                                = 0
read(3, "10632\n", 128)                 = 6
read(3, "", 128)                        = 0
close(3)                                = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17552
--- SIGCHLD (Child exited) @ 0 (0) ---
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,    child_tidptr=0xb76f8728) = 17553
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17553
--- SIGCHLD (Child exited) @ 0 (0) ---
write(1, "Preparing file 10632 of ", 24Preparing file 10632 of ) = 24
write(1, "51041073(7) ....", 1651041073(7) ....)        = 16
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD,    child_tidptr=0xb76f8728) = 17554
close(4)                                = 0
read(3, "8\n", 128)                     = 2
read(3, "", 128)                        = 0
close(3)                                = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 17554
--- SIGCHLD (Child exited) @ 0 (0) ---
pipe([3, 4])                            = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0xb76f8728) = 17555
close(4)                                = 0
read(3, "", 128)                        = 0
close(3)                                = 0
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGSEGV}], 0, NULL) = 17555
--- SIGCHLD (Child exited) @ 0 (0) ---
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault

Сценарий ниже:

#!/bin/sh
#----VARS----
prefix="10.0.3.2/read/"
oprdir="/home/andrew/doc/read/"
throttle=0

#----------------
x=5000
advcount=0
count=`curl "$prefix""count.php" 2> /dev/null`

#----Funcs----
getline()
{
  #Run curl to get the line of text
  #TODO -n
  echo -n "Preparing file" $x "of "
  if [ $advcount -ge 25 ]
  then
    count=`curl "$prefix""count.php" 2> /dev/null`
    advcount=0
  fi
  echo -n $count"("$advcount")" "...."
  advcount=`expr $advcount + 1`

  line=`curl "$prefix""testfile-prep.php?x=$x" 2> /dev/null`
  if [ "$line" = "ERR ERROR: X OUTSIDE RECORDS." ]
  then
    echo "ERROR: X OUTSIDE DB... WAITING TO RETRY."
    sleep 60
    getline
  fi
  prepline
}

prepline()
{
  echo $line | sed 's/^[0-9]*\./\n./g' | sed 's/\([a-zA-Z]*\)\./\1\n./g'  | sed 's/\,/\n\,/g' | sed 's/(\(.*\)/(\n\1/g' | sed 's/\(.*\))/\1\n)/g' | sed 's/ /\n/g'> out-0-$x.dat
  echo "OK!"
  #cat out-$x.dat
  advance
}
advance()
{
  x=`expr $x + 1`
  sleep $throttle
  getline
}

cd "$oprdir"
getline

Извините за новеллуинформация, любая помощь приветствуется.

1 Ответ

4 голосов
/ 20 декабря 2011

У вас переполнение стека .

Ваша getline функция вызывает prepline, что вызывает advance, что вызывает getline.

Вы должны использовать какой-то цикл вместо того, чтобы вызывать саму функцию в неисключительном состоянии. (Самостоятельный вызов в случае ошибки в порядке, у вас не будет 5000 ошибок, переполняющих стек.)

...