Форум программистов, компьютерный форум, киберфорум
C++: Сети
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
1

Подскажите как найти странную ошибку !

17.09.2009, 12:04. Показов 2525. Ответов 27
Метки нет (Все метки)

Всем привет !

Написал многопоточный сервер

использовал

Код
         winsock2.h // для сокетов

         CreateThread() // для создания потоков

         
         InitializeCriticalSection(&M_CS);   // для кретических секций


Сервер работает в норме - но 1 раз в сутки может выдать

Подскажите как найти странную ошибку !


Как узнать что ему не хватает - ? Или потоки сталкиваются - тогда как узнать на каких данных ?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.09.2009, 12:04
Ответы с готовыми решениями:

Выдает Странную ошибку
Ребят не могу разобраться выходит вот такая вот ошибка в моем коде Parse error: syntax error,...

PascalABC.NET выдает странную ошибку при запуске
При запуске программы Pascal возмущается(см. картинку), не понимаю чего он требует. А вот и код:...

Подскажите как найти ошибку
Помогите найти ошибку. Вот условие задачи: n заготовок необходимо обработать на двух одинаковых...

Подскажите как найти ошибку в сортировке массива по возрастанию
Кто может объясните пожалуйста не могу разобраться с сортировкой нужно отсортировать массив так...

27
1664 / 1133 / 80
Регистрация: 21.08.2008
Сообщений: 4,725
Записей в блоге: 1
17.09.2009, 12:29 2
понаставить try - catch и логировать исключения
а вообще достаточно просто внимательно посмотреть где идет выделение и удаление памяти и какие объекты могут обращаться на удаленную память
0
229 / 67 / 11
Регистрация: 02.06.2009
Сообщений: 280
17.09.2009, 12:35 3
Цитата Сообщение от malik555 Посмотреть сообщение
Как узнать что ему не хватает - ? Или потоки сталкиваются - тогда как узнать на каких данных ?
Жмакнуть отмена и глянуть в дебугере.
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
17.09.2009, 12:42  [ТС] 4
Цитата Сообщение от Alexandoros Посмотреть сообщение
Жмакнуть отмена и глянуть в дебугере.

У меня visual c++ 6 , после того как нажму отмена - как попасть в дебугер ?
0
229 / 67 / 11
Регистрация: 02.06.2009
Сообщений: 280
17.09.2009, 12:49 5
Автоматом окно появится. Если не появится - установи галку Options-Debug - Just In Time debugger.
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
17.09.2009, 22:51  [ТС] 6
понаставить try - catch и логировать исключения
а вообще достаточно просто внимательно посмотреть где идет выделение и удаление памяти и какие объекты могут обращаться на удаленную память
Если я ставлю блок try - catch то ошибка всеравно появляется

например
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
           // создаю поток
            CreateThread();
 
          // клиент уже находится в новом потоке
 
          //ошибка происходить в цыкле while - я его весь поставил в блок try
 
         try{
 
 
              while(1){
 
                         recv(client, buffer, sizeof(buffer),0); 
                         // читаю данные и обробатываю !
               
              }
 
         throw "Error !!!";
         }catch(string sdf){
 
 
    cout << sdf;                  
         }
Походу если произойдет ошибка в блоке try - то мое приложение не должно остановится а
просто выдаст Error !!! ?

Но ошибка остается и Error !!! не выдает !
0
2342 / 498 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
18.09.2009, 10:14 7
а ты уверен, что так правильно:
Цитата Сообщение от malik555 Посмотреть сообщение
recv(client, buffer, sizeof(buffer),0);
ты считываешь данные в буфер, а длину указываешь не буфера, а указателя на буфер.
само собой, что при исполнении recv() идет ошибка доступа в системном потоке.
потому и try - catch молчит; поток-то не твой, а системный.

если у тебя так в рабочем коде и написано, то ошибка совсем даже не странная.
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
18.09.2009, 11:02  [ТС] 8
а ты уверен, что так правильно:
Спасибо большое ! Я понял - в манах там чуть по другому - щас переделаю .

Вот я выбрал главные части из кода - посмотрите может еще что будет .
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// после  listen()
 
                 // ждем подключения
 
                 for(;;)
                 {
 
                             client = accept( ListenSocket, NULL, NULL );
                             if( client == INVALID_SOCKET ){
                             break;
                             }
 
                             if(CreateThread(NULL, 0, NewClient, (LPVOID)client, 0, &dwThreadId)==NULL){
                             break;
                             }
 
 
                 }
 
 
                 DWORD WINAPI NewClient(LPVOID lpParam){
 
                        ClientData::Info((int)lpParam);
 
                 }
 
 
 
                 //
                 #define bzero(a) memset(a,0,sizeof(a));
 
                 class ClientData{
 
 
                 public:
 
 
                 static void Info(int client)
                 {
 
                      char buffer[1024];
                      bzero(buffer);
 
                      while(1){
 
 
                              recv(client, buffer, sizeof(buffer),0);
 
                              if(strcmp(buffer, (char *)"")==0){
                                 cout << "disconnect !!!";
                              }
 
                              // Дальше обробатываю данные !
 
 
                      bzero(buffer);
                      }
 
 
 
                 }
 
 
 
 
                 }
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
18.09.2009, 15:42  [ТС] 9
recv() я переделал
C++
1
2
3
4
5
6
                      char buffer[10240];
               int recvbuflen = 1024;
               int recvStatus = 0;
 
 
                      recvStatus = recv(client, buffer, recvbuflen,0);
Но ошибка остается


Подскажите как найти странную ошибку !


Подскажите как найти странную ошибку !


Подскажите как найти странную ошибку !
0
2342 / 498 / 22
Регистрация: 01.04.2009
Сообщений: 2,200
18.09.2009, 17:27 10
Цитата Сообщение от malik555 Посмотреть сообщение
Но ошибка остается
тогда еще вопрос: а почему ты решил, что ошибка возникает именно там?
лучше весь код покажи, а то мы тут еще полгода гадать будем.
0
229 / 67 / 11
Регистрация: 02.06.2009
Сообщений: 280
18.09.2009, 18:10 11
Если я ставлю блок try - catch то ошибка всеравно появляется
Оно и не удивительно - дефолтом try+catch не ловит структурные ексепшены. Читаем мсдн (/EH).

recv(client, buffer, sizeof(buffer),0);
Если char buffer[1024], то это хорошая запись.

Но ошибка остается
И, для танкистов, на бис, Жмакнуть отмена и глянуть в дебугере, где ошибка произошла
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
18.09.2009, 21:14  [ТС] 12
Цитата Сообщение от Alexandoros Посмотреть сообщение

И, для танкистов, на бис, Жмакнуть отмена и глянуть в дебугере, где ошибка произошла

Я выложил 3 картинки из дебугера - только немогу понять как определить что за ошибка
0
0 / 0 / 0
Регистрация: 18.09.2009
Сообщений: 5
18.09.2009, 21:55 13
эта ошибка связана с нарушением доступа к памяти...
чаще всего происходит при использовании не проинициализированых укзателей,
или указатель указывает на уже несуществующую переменную,или используешь
переменную которая у мерла давно в другом потоке,запусти в дебагере в VC 6
и будет все ясно!
0
MCSD: APP BUILDER
8791 / 1070 / 104
Регистрация: 17.06.2006
Сообщений: 12,603
18.09.2009, 22:38 14
malik555,
Как узнать что ему не хватает - ?
Код без единого assert'а = говнокод.
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
19.09.2009, 02:35  [ТС] 15
Цитата Сообщение от Glushitel Посмотреть сообщение
эта ошибка связана с нарушением доступа к памяти...
чаще всего происходит при использовании не проинициализированых укзателей,
или указатель указывает на уже несуществующую переменную,или используешь
переменную которая у мерла давно в другом потоке,запусти в дебагере в VC 6
и будет все ясно!


В дебагере показывает функцию где произошла ошибка и указывает на строку где просто break; - чем это ему break; не нравится .
0
0 / 0 / 0
Регистрация: 18.09.2009
Сообщений: 5
19.09.2009, 10:03 16
Цитата Сообщение от malik555 Посмотреть сообщение
В дебагере показывает функцию где произошла ошибка и указывает на строку где просто break; - чем это ему break; не нравится .
значит это произходит до break; глянь на сообщение:
обратилась по адресу 0х00000004
такого адреса быть неможет! это пальцем в небо!!!

а потом ты применяшь ф-ции recv и send без select ,а они делают возврат
независимо есть че в сокете или нет,ждать небудут! почитай MSDN
попробуй вот это,хотя ошибка скорее всего кроется в другом
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int RECV(SOCKET s,char *buf, int len, int flag, int nSec)
{
  TIMEVAL tv={nSec,0};
  FD_SET  fd={1,s};
  int bytes_recv;
          if(!select(0,&fd,0,0,&tv))
          {
            return -2; 
          }         
          bytes_recv=recv(s, buf, len, flag);
 
return bytes_recv;
}
//---------------------------------------------------------------
int SEND(SOCKET s,const char *buf, int len, int flag, int nSec)
{
         
  TIMEVAL tv={nSec,0};
  FD_SET  fd={1,s};
  int bytes_send;
         if(!select(0,0,&fd,0,&tv))
          {
            return -2; 
          }
          bytes_send=send(s, buf, len, flag);
 
return bytes_send;
}//int nSec значение таймаута,т.е сколько ждать данные в секундах
0
4 / 4 / 3
Регистрация: 01.07.2009
Сообщений: 127
19.09.2009, 11:41  [ТС] 17
Спасибо за помощь ребята но нефига не помогает !

Я методом втыка начал коментировать куски кода - вобщем вырезал все что было - остался голый сокет сервер , сегодня ночью поставил его на тест и утром пришел - "СЕРВЕР УПАЛ !" - он упал на 4048 запросе !


Вот исходник который я упростил до минимума - если кого не затруднит посмотрите !
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
   #include "winsock2.h"
   #include <stdio.h>   
   #include <iostream>
   #include <map> 
   #include <sstream>
   #include <string>                            
   using namespace std;
 
#include "_login.h"
 
 
CRITICAL_SECTION M_CS;
 
 
HANDLE        hThread;
DWORD         dwThreadId;
 
 
 
 DWORD WINAPI NewClient(LPVOID lpParam){
   
       _login::start((int)lpParam);
       return 0;
   }
 
 
int main(){
             
            
    
              InitializeCriticalSection(&M_CS);
 
 
              WSADATA wsaData;
              int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
              if (iResult != NO_ERROR){
              printf("Error at WSAStartup()\n");
       exit(0);
              }
 
 
              SOCKET ListenSocket , client ;
              ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
              if (ListenSocket == INVALID_SOCKET) {
              printf("Error at socket(): %ld\n", WSAGetLastError());
       exit(0);
       }
 
              sockaddr_in service;
       service.sin_addr;
              service.sin_family = AF_INET;
              service.sin_addr.s_addr = inet_addr("127.0.0.1");
              service.sin_port = htons(5190);
 
              if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) {
              printf("bind() failed.\n");
              closesocket(ListenSocket);
       exit(0);
       }
  
              if(listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR){
         exit(0);
       }
        
             
 
for(;;){
 
             client = accept( ListenSocket, NULL, NULL );
             if( client == INVALID_SOCKET ){
         break;
      }      
                      
   
       if(CreateThread(NULL, 0, NewClient, (LPVOID)client, 0, &dwThreadId)==NULL){
          break;
       }      
                          
}            
 
 
  return 0;
}
 
 
 
 
 
// #include "_login.h"
 
 
class _login {
 
public:
 
      static int start(int client)
      {
          
          
          char buffer[10240];
          int recvbuflen = 1024;
          int recvStatus = 0;
          
          while(1){
 
             recvStatus = recv(client, buffer, recvbuflen,0);
 
                    if(recvStatus == SOCKET_ERROR){  
                       return 0;
             }
                                  if(recvStatus==0){    
                                     return 0;
            }
          
                    char mes[] = "Helo !!!";
                                  send(client, mes, strlen(mes)+1, 0);
                    
                    break;
          }
          
              closesocket(client); 
              return 0;
      }
 
};
0
555 / 509 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
19.09.2009, 13:59 18
в уставе прописано:

"The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle. "

а вы даже не сохраняете хэндлы, которые массово плодите, не говоря о том, чтобы их закрывать.

(
C++
1
2
3
       if(CreateThread(NULL, 0, NewClient, (LPVOID)client, 0, &dwThreadId)==NULL){
          break;
       }
)
система не может их создавать бесконечное количество.

предполагаю, что если ваш трейд не будет ничего делать, просто return; вы получите тот же эффект.
0
0 / 0 / 0
Регистрация: 18.09.2009
Сообщений: 5
19.09.2009, 15:25 19
Цитата Сообщение от malik555 Посмотреть сообщение
Спасибо за помощь ребята но нефига не помогает !

Я методом втыка начал коментировать куски кода - вобщем вырезал все что было - остался голый сокет сервер , сегодня ночью поставил его на тест и утром пришел - "СЕРВЕР УПАЛ !" - он упал на 4048 запросе !


Вот исходник который я упростил до минимума - если кого не затруднит посмотрите !



Код

   #include "winsock2.h"
   #include <stdio.h>   
   #include <iostream>
   #include <map> 
   #include <sstream>
   #include <string>                            
   using namespace std;

#include "_login.h"


CRITICAL_SECTION M_CS;


HANDLE        hThread;
DWORD         dwThreadId;



 DWORD WINAPI NewClient(LPVOID lpParam){
   
	   _login::start((int)lpParam);
	   return 0;
   }


int main(){
             
	        
	
	          InitializeCriticalSection(&M_CS);


              WSADATA wsaData;
              int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
              if (iResult != NO_ERROR){
              printf("Error at WSAStartup()\n");
	   exit(0);
              }


              SOCKET ListenSocket , client ;
              ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
              if (ListenSocket == INVALID_SOCKET) {
              printf("Error at socket(): %ld\n", WSAGetLastError());
	   exit(0);
	   }

              sockaddr_in service;
	   service.sin_addr;
              service.sin_family = AF_INET;
              service.sin_addr.s_addr = inet_addr("127.0.0.1");
              service.sin_port = htons(5190);

              if (bind( ListenSocket, (SOCKADDR*) &service, sizeof(service)) == SOCKET_ERROR) {
              printf("bind() failed.\n");
              closesocket(ListenSocket);
	   exit(0);
	   }
  
              if(listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR){
	     exit(0);
	   }
	    
			 

for(;;){

             client = accept( ListenSocket, NULL, NULL );
             if( client == INVALID_SOCKET ){
	     break;
	  }      
					  
   
	   if(CreateThread(NULL, 0, NewClient, (LPVOID)client, 0, &dwThreadId)==NULL){
	      break;
	   }	  
			   			  
}			 


  return 0;
}





// #include "_login.h"


class _login {

public:

	  static int start(int client)
	  {
          
		  
		  char buffer[10240];
		  int recvbuflen = 1024;
		  int recvStatus = 0;
		  
		  while(1){

			 recvStatus = recv(client, buffer, recvbuflen,0);

		            if(recvStatus == SOCKET_ERROR){  
		               return 0;
			 }
                                  if(recvStatus==0){    
                                     return 0;
			}
          
		            char mes[] = "Helo !!!";
                                  send(client, mes, strlen(mes)+1, 0);
					
		            break;
		  }
		  
              closesocket(client); 
              return 0;
	  }

};
вот сомтри тепер на этот код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
for(;;){
 
             client = accept( ListenSocket, NULL, NULL );
             if( client == INVALID_SOCKET ){
         break;
      }      
                      
   
       if(CreateThread(NULL, 0, NewClient, (LPVOID)client, 0, &dwThreadId)==NULL){
          break;
       }      
                          
}
А что произойдет если сокет "client" попытается использовать еще один поток!
Ведь CreateThread небудет ждать пока твой NewClient выполнится,а выход из CreateThread
будет сразу после запуска....и выполнение перейдет на accept снова...

можеш поробовать так:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SOCKET client;//глобально обьяви
for(;;){
            SOCKET client2;
             client = accept( ListenSocket, NULL, NULL );
             if( client == INVALID_SOCKET ){
         break;
      }      
    EnterCriticalSection(&M_CS);                  
              memcpy(&client,client2,sizeof(SOCKET));
           
       if(CreateThread(NULL, 0, NewClient, (LPVOID)client2, 0, &dwThreadId)==NULL){
                  LeaveCriticalSection(&M_CS);
          break;
       }      
    LeaveCriticalSection(&M_CS);                      
}//незабудь по завершению своего сервера вызвать DeleteCricalSection
Добавлено через 25 минут
извеняюсь ошибочка....
memcpy(&client2,client,sizeof(SOCKET));
вот так правельно
0
555 / 509 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
19.09.2009, 18:51 20
ctl+alt+del->Processes
появится task manager. посмотрите, видна ли колонка handles, и если нет, то:

view->select columns->handle count

потом запустите ваш процесс и смотрите как будет расти это число. когда оно достигнет 4096 (кажется), ваше приложение вывалится.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.09.2009, 18:51

Подскажите как исправить ошибку. прога ломается на 79 строке. а ошибку не выдает
#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;ctime&gt; using namespace std; int chisla(int...

Не могу найти ошибку, подскажите
#include &quot;stdafx.h&quot; #include &quot;iostream&quot; #include &quot;math.h&quot; #include &quot;cmath&quot; using...

Не могу найти ошибку, подскажите=))
Подскажите где сдесь ошибка????? #include&lt;iostream.h&gt; #include&lt;math.h&gt; const int n=3, m=0;...

Не могу найти ошибку, подскажите пожалуйста
Два элемента div. по нажатию на один из них, второму присваивается display:none; По второму...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.