The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]



Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX
Режим отображения отдельной подветви беседы [ Отслеживать ]

Оглавление

Проблема с серверной частью программы, Dima (?), 01-Сен-02, (0) [смотреть все]

Сообщения [Сортировка по времени | RSS]


1. "RE: Проблема с серверной частью программы"  +/
Сообщение от Арлекинemail (?), 02-Сен-02, 08:02 
В соляре SIGCHLD ловить не обязательно. Можно просто временами вызывать wait(&status)если ПОРОЖДЕННЫЙ процесс УЖЕ закончился, она все равно ответит кодом процесса, который закончился. Подробнее не помню, но в манах все есть.
Ну и проще всего, хотя и неправильно в общем случае, килять в подпроцессе самого себя, "наизлете". Вот только тогда родительский wait получит код убийства (SIGTERM, SIGINT, ...).
Ответить | Правка | Наверх | Cообщить модератору

2. "RE: Проблема с серверной частью программы"  +/
Сообщение от Dimaemail (?), 02-Сен-02, 14:07 
>В соляре SIGCHLD ловить не обязательно. Можно просто временами вызывать wait(&status)если ПОРОЖДЕННЫЙ
>процесс УЖЕ закончился, она все равно ответит кодом процесса, который закончился.
>Подробнее не помню, но в манах все есть.
>Ну и проще всего, хотя и неправильно в общем случае, килять в
>подпроцессе самого себя, "наизлете". Вот только тогда родительский wait получит код
>убийства (SIGTERM, SIGINT, ...).

К сожалению у меня не солярка.... я под openbsd пишу, на счёт килять самого себя, идея не плохая, надо будет попробовать! Спасибо!

Ответить | Правка | Наверх | Cообщить модератору

3. "RE: Проблема с серверной частью программы"  +/
Сообщение от Dimaemail (?), 03-Сен-02, 12:02 
>>В соляре SIGCHLD ловить не обязательно. Можно просто временами вызывать wait(&status)если ПОРОЖДЕННЫЙ
>>процесс УЖЕ закончился, она все равно ответит кодом процесса, который закончился.
>>Подробнее не помню, но в манах все есть.
>>Ну и проще всего, хотя и неправильно в общем случае, килять в
>>подпроцессе самого себя, "наизлете". Вот только тогда родительский wait получит код
>>убийства (SIGTERM, SIGINT, ...).
>
>К сожалению у меня не солярка.... я под openbsd пишу, на счёт
>килять самого себя, идея не плохая, надо будет попробовать! Спасибо!

Добавил в конце дочернего тела  kill(getpid(),SIGKILL);
и тот же результат, остаётся зомби процесс, родительский в любом случае должен обработать сообщение от дочернего...

Чего делать, на знаю...

Ответить | Правка | Наверх | Cообщить модератору

4. "RE: Проблема с серверной частью программы"  +/
Сообщение от Dimaemail (?), 03-Сен-02, 12:21 
Вся проблема-то ещё и в том, что родительский процесс перестаёт принимать соединения если даже я просто сделаю обработчик дочерних сигналов ( signal(SIGCHLD, sig_child); ) а в теле функции sig_child будет пусто.
Ответить | Правка | Наверх | Cообщить модератору

5. "RE: Проблема с серверной частью программы"  +/
Сообщение от Арлекинemail (?), 03-Сен-02, 12:50 
Ты return-то не забыл в перехватчик воткнуть ? А то она не факт, что вернется. Проверено.
Ответить | Правка | Наверх | Cообщить модератору

6. "RE: Проблема с серверной частью программы"  +/
Сообщение от Dimaemail (?), 03-Сен-02, 12:55 
>Ты return-то не забыл в перехватчик воткнуть ? А то она не
>факт, что вернется. Проверено.

Возможно что и забыл, как это например делается?

Ответить | Правка | Наверх | Cообщить модератору

7. "RE: Проблема с серверной частью программы"  +/
Сообщение от Арлекинemail (?), 03-Сен-02, 12:58 
void sig_catcher( int sig_num )
{
  /* пустой перехватчик */
  return;   // чтоб гарантированно вернул стек на точку вызова
}
Ответить | Правка | Наверх | Cообщить модератору

8. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Арлекинemail (?), 03-Сен-02, 12:59 
А то kernel panic может случиться )
Ответить | Правка | Наверх | Cообщить модератору

9. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Dimaemail (?), 03-Сен-02, 13:15 
>А то kernel panic может случиться )

Всё равно не фига...
Я сделал чтобы прога писала стадию выполнения главного цикла, вот что получаю:

Tue Sep  3 13:03:02 2002: go to background sucessfull
Tue Sep  3 13:03:02 2002: start complete. accept connections!
main loop... next select (самое начало, ждём select();)
main loop... after select (в данном случае получили соединеие и это место уже после селекта)
main loop... next accept (Перед принятием соединения)
Accept connection... next fork (Соединение успешное, делаем форк)
main loop... next select (почему-то процесс перешёл на начало цикла..)
fork() (делаем форк)
child (это функция из дочернего процесса (она читает сокет и отправлет что надо в него, потом просто выходит))
Tue Sep  3 13:04:10 2002: Login successful (login 'al' from host '172.16.32.3' action 0) (результат успешной авторизации клиентского приложения)
exit(0) //from child proc.
sig_child... (это когда родитель выполняет функцию по событию от дочернего процесса)
main loop... after select (почему-то оказывается что селект что-то получил, и дальше ни чего не происходит.)

куски кода:

void sig_child(int sig)
{
int status;

while (waitpid(-1, &status, WNOHANG) > 0) ;

fprintf(logfile, "sig_child...\n");
fflush(logfile);

return;
}

/* main cycle  */
for(;;)
{
  fprintf(logfile, "main loop... next select\n");
  fflush(logfile);

  set = master;
  select(FD_SETSIZE, &set, NULL, NULL, NULL);
  fprintf(logfile, "main loop... after select\n");
  fflush(logfile);
  
  if ( FD_ISSET(ctlsock, &set) )
  { ctl_read_upcall(ctlsock); }

  if ( FD_ISSET(sockfd, &set) )
  {
   cl_len = sizeof(struct sockaddr_in);
   fprintf(logfile, "main loop... next accept\n");
   fflush(logfile);
  
   if ( (newsockfd = accept(sockfd, (struct sockaddr *)&client, &cl_len)) == -1)
   {
    c_error++;
    time(&timeval); memcpy(ctimeval, ctime(&timeval), strlen(ctime(&timeval))-1);
    fprintf(logfile, "%s: accept socket error (*)\n", ctimeval);
    fflush(logfile);
    continue;
   }
   fprintf(logfile, "Accept connection... next fork\n", ctimeval);
   fflush(logfile);

   /* Create new process (fork) and etc... */
   c_auth_accept++;
   if ( fork() == 0 )
   {
    fprintf(logfile, "fork()\n");
    fflush(logfile);
    childproc();
    close(newsockfd);
    exit(0);
   }
   close(newsockfd);
  }
}

Ответить | Правка | Наверх | Cообщить модератору

10. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Арлекинemail (?), 03-Сен-02, 13:38 
Поставь на каждый вызов по Фпринтфу, чтоли. Хоть ясно станет где конкретно она задумалась. Я последнее время от С отошел несколько, да и как-то нечитабельно выглядит... Уж извини.
Ответить | Правка | Наверх | Cообщить модератору

11. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Dimaemail (?), 03-Сен-02, 14:04 
>Поставь на каждый вызов по Фпринтфу, чтоли. Хоть ясно станет где конкретно
>она задумалась. Я последнее время от С отошел несколько, да и
>как-то нечитабельно выглядит... Уж извини.

Ладно, спасибо, буду разбираться....

Спасибо!

Ответить | Правка | Наверх | Cообщить модератору

12. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от idle (?), 03-Сен-02, 23:25 
Вы совсем заговорились :)

> Ты return-то не забыл в перехватчик воткнуть ?
> А то она не факт, что вернется. Проверено.

Значит, надо выкидывать компилятор. Обработчик
сигнала - обычная функция, явный return в конце
не нужен.

Предлагаю скомпилировать оба варианта и сравнить
исполняемые файлы с помощью cmp. Они совпадут.

> А то kernel panic может случиться )

Значит, надо выкидывать ядро, если таким
(или другим) способом можно вызвать panic.


Если не интересует exit_code порожденных
процессов, можно поставить SIG_IGN на SIGCHLD,
зомби не будет.

Функцией signal() вообще не стоит пользоваться,
она ведет себя немного по-разному в разных системах
и даже версиях libc. Пользуйтесь sigaction().

> main loop... next select (почему-то процесс перешел на начало цикла..)

Он и должен перейти, это же parent, fork() вернул не 0.

> main loop... after select (почему-то оказывается что селект
> что-то получил, и дальше ни чего не происходит.)

После того, как child умрет, процессу посылается SIGCHLD
(если не SIG_DFL || SIG_IGN). В случае получения процессом
не блокированного сигнала, select() вернет EINTR и в set мусор -
это нужно проверять!!!! Поэтому и не происходит ничего.
Например, очень может быть, что FD_ISSET(ctlsock, &set) == 1,
и процесс сидит в ctl_read_upcall(ctlsock).

Без обид, лучше бы прочитать man select, man signal etc,
чем сразу писать в форум, быстрее бы получилось.

P.S. Если каждый раз после fprintf(logfile, ...) стоит
fflush(logfile), то на хрена fprintf(), если есть write()?

Ответить | Правка | К родителю #9 | Наверх | Cообщить модератору

13. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Арлекинemail (?), 04-Сен-02, 07:47 
> Ты return-то не забыл в перехватчик воткнуть ?
> А то она не факт, что вернется. Проверено.
>
>Значит, надо выкидывать компилятор. Обработчик
>сигнала - обычная функция, явный return в конце
>не нужен.
Вот тебе пример ситуации - спарковский компилер именно так и делает. Не всегда корректно идет из перехватчиков - толи longjmp хочет, толи еще чего - не искал. Но он ЛИЦЕНЗИОННЫЙ. И ОРАКЛ на "боевых" спарковских системах тоже. И в лицензии к последнему черным по белому написано - все разработки только лицензированными для платформы продуктами из списка. Список есть. gcc, etc в списке нет. Мне выкинуть спарковский компилер и штрафы, случись чего, ты платить будешь ? :) По мне проще пустой ретурн поставить.

> А то kernel panic может случиться )
>
>Значит, надо выкидывать ядро, если таким
>(или другим) способом можно вызвать panic.
Не буду ввязываться в длительную дискуссию, но если уж и выкидывать ядра, то те которые помирают молча. Очень любили это мандрейк 7.какой-то и Valinux, например. А соляркина паника есть ничто иное как обычное сообщение. Еще ни разу не то что ядро не сдохло, но и лишнего процесса не прибилось. А корки в 2гига регулируются ulimit'ом. Оракляндцы - вот большие спецы вызывать такие ситуации, и если бы после каждой приходилось лечить ось или железку я в первую очередь избавился бы от оси. :)

Ответить | Правка | Наверх | Cообщить модератору

14. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Dimaemail (?), 04-Сен-02, 11:02 
Сделал я вот так:

memset(&act_chd, 0, sizeof(act_chd));
act_chd.sa_handler = SIG_IGN;
act_chd.sa_flags = SA_NOCLDWAIT;
sigemptyset(&act_chd.sa_mask);
sigaction(SIGCHLD, &act_chd, (struct sigaction *)0);

и зомби всё равно остаются.. ( ос openbsd 3.0 )
:((((

Ответить | Правка | Наверх | Cообщить модератору

15. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Dimaemail (?), 04-Сен-02, 12:01 
>Сделал я вот так:
>
> memset(&act_chd, 0, sizeof(act_chd));
> act_chd.sa_handler = SIG_IGN;
> act_chd.sa_flags = SA_NOCLDWAIT;
> sigemptyset(&act_chd.sa_mask);
> sigaction(SIGCHLD, &act_chd, (struct sigaction *)0);
>
>и зомби всё равно остаются.. ( ос openbsd 3.0 )
>:((((

Всем спасибо!!!!!
Я победил эту фигню, короче после очередного вызова select возращал ошибку (-1) и errno было 4 (проблема с сигналами), сделал если селект меньше 0, то continue, неправильно конечно, но работает!!!!
Всем спасибо! Извините за шум!

Ответить | Правка | Наверх | Cообщить модератору

16. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от idle (?), 04-Сен-02, 20:03 
> > > Ты return-то не забыл в перехватчик воткнуть ?
> > > А то она не факт, что вернется. Проверено.
> >
> > Значит, надо выкидывать компилятор. Обработчик
> > сигнала - обычная функция, явный return в конце
> > не нужен.
> >
> Вот тебе пример ситуации - спарковский компилер именно так и делает.

То есть, этот компилятор генерит разный код для:

void f1(int sig) {}
void f2(int sig) { return; }

Что-то не верится. Может, запостишь asm выход?

> А соляркина паника есть ничто иное как обычное сообщение.

Ну тут вопрос терминологии, под kernel panic обычно
подразумевают крах системы.

> короче после очередного вызова select возращал ошибку (-1)
> и errno было 4 (проблема с сигналами), сделал если селект меньше 0,
> то continue, неправильно конечно, но работает!!!!

Это как раз правильно, а errno 4 и есть EINTR.

Ответить | Правка | К родителю #15 | Наверх | Cообщить модератору

17. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Арлекинemail (?), 05-Сен-02, 07:55 
Давай будем проще. Постить асмы сюда - во-первых дело не совсем правильное, во-вторых ассемблер не интеловский, я в нем никогда не ковырялся и вряд ли что-то пойму сходу, а вникать нет ни времени ни особого желания. Вот тебе результаты с размерами модулей и их исходники:
07:48:00 @newgoblin:bin >more test.C
#include <stdio.h>
void sgc() {
return;
}
main() {
}
07:47:47 @newgoblin:bin >CC test.C -o test
07:48:26 @newgoblin:bin >more test1.C
#include <stdio.h>
void sgc() {
}
main() {
}
07:47:47 @newgoblin:bin >CC test1.C -o test1
07:47:56 @newgoblin:bin >ls -laF test*
-rwxr-xr-x   1 it_devel voice       8068 Sep  5 07:46 test*
-rw-r--r--   1 it_devel voice         54 Sep  5 07:46 test.C
-rwxr-xr-x   1 it_devel voice       8064 Sep  5 07:47 test1*
-rw-r--r--   1 it_devel voice         46 Sep  5 07:47 test1.C
Гнутого "вблизи" нет, как-нибудь потом проверю.
Если есть непременное желание удостовериться и выяснить чего там сантехники наваяли, ищи спарк-машину со SPARC C++ 4.1 компилером (solars 6-8 ) и рой. Однако, судя по разности длин, именно 4 байта и есть тот самый jmp.
ЗЫЖ Это не первый и не последний пример "уникальности" ЭТОГО компилера.
Ответить | Правка | К родителю #16 | Наверх | Cообщить модератору

18. "RE: Только 11-й сигнал не лови так"  +/
Сообщение от Арлекинemail (?), 05-Сен-02, 08:06 
> А соляркина паника есть ничто иное как обычное сообщение.
>Ну тут вопрос терминологии, под kernel panic обычно
>подразумевают крах системы.
Не совсем так. Kernel Panic - это ситуация, когда ядро не в состоянии гарантированно завершить только процесс - источник аварии, ибо само не гарантирует целостность памяти, семафоров и пр. в окружении того процесса. Я еще не встречал ситуаций, хотя ее можно попробывать смоделировать, чтоб упало само ядро. Речь только о SunSolaris, прошу заметить. Но сам процесс каков! На 6-й оси, где однонитевое ядро, на 2-х процессорном серваке, 2-х гиговая (signed int на СПАРКе 4 байта) корка пишется на диск около минуты и в это время даже консоль не отвечает. Вообще никакой реакции ни на что, и на прерывания в т.ч. Таким образом ядро спасает себя - и это ИМХО правильно, когда одно приложение не может явиться причиной краха всей системы, хоть бы это приложение и самое центровое в ней.

Ответить | Правка | К родителю #16 | Наверх | Cообщить модератору

19. "RE: А это от gcc"  +/
Сообщение от Арлекинemail (?), 05-Сен-02, 08:18 
root@is-tester:/export/home/root$ more test1.C
#include <stdio.h>
void sgc()
{
return;
}
main() {
}
root@is-tester:/export/home/root$ gcc test1.C -o test1
root@is-tester:/export/home/root$ more test.C
#include <stdio.h>
void sgc()
{
}
main() {
}
root@is-tester:/export/home/root$ gcc test.C -o test
root@is-tester:/export/home/root$ ls -laF test*
-rwxr-xr-x   1 root     other       5996 Sep  5 08:21 test*
-rw-r--r--   1 root     other         45 Sep  5 08:21 test.C
-rw-r--r--   1 root     other      21882 Apr  9 11:17 test.dat
-rwxr-xr-x   1 root     other       6004 Sep  5 08:22 test1*
-rw-r--r--   1 root     other         53 Sep  5 08:22 test1.C
Ответить | Правка | К родителю #16 | Наверх | Cообщить модератору

20. "RE: А это от gcc"  +/
Сообщение от idle (?), 06-Сен-02, 00:49 
> Давай будем проще. Постить асмы сюда - во-первых дело не совсем правильное,

А что так? Строгий секрет, государственная тайна?
У этого компилятора -S ключ есть? Вот и скажи CC -S на:

      void f1(int sig) {}
      void f2(int sig) { return; }

Но! Не забудь хотя бы _минимальную_ оптимизацию включить!
Не знаю, как твой CC, но gcc без -O (хотя бы) компилирует
буквально по тексту - отсюда и разница в размерах.
Мне просто любопытно.

> Не совсем так. Kernel Panic - это ситуация,

Ну говорю же, разница в терминологии, что тут обсуждать.

Ответить | Правка | К родителю #19 | Наверх | Cообщить модератору

21. "RE: А это от gcc"  +/
Сообщение от Арлекинemail (?), 06-Сен-02, 08:48 
Ерничаем ? Это я насчет тайны. Какой смысл забивать форум двухэкранными листингами? Если я захочу что-то подправить или подменить я и так это сделаю. Если ты хочешь посмотреть на спарковский ассемблер могу тебе его описание в пдф выслать. Но не суть.
Значит так:
- с оптимизатором гнутый и в самом деле делает одинаковый код.
- спарк делает одинаковый на -О4 и -О5 (что там за варианты оптимизации не помню).
К сожалению (моему) я, видимо, избалован хорошей техникой, ибо оптимизаторами вообще не пользуюсь. Правда дебуг отключаю ! ))
ЗЫЖ Ораклячий OCI (мне именно с ним плотно приходится иметь дело последние годы) как-то странно относится к оптимизации, требуя оптимизировать все, кроме ЕГО файлов. У них, как обычно, либо кривой код, либо явная адресация на асме... Не люблю я их, как можно заметить...

Завязываем на том что ты прав.

Ответить | Правка | К родителю #20 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру