Changeset 9240 in orxonox.OLD for trunk/src/util
- Timestamp:
- Jul 6, 2006, 12:25:44 PM (18 years ago)
- Location:
- trunk/src/util
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/util/signal_handler.cc
r8293 r9240 21 21 #ifndef __WIN32__ 22 22 23 #include <wait.h> 24 23 25 SignalHandler::SignalHandler() 24 26 { 25 27 } 26 28 27 void SignalHandler::doCatch( std::string appName, GdbRunType type ) 28 { 29 this->type = type; 29 void SignalHandler::doCatch( std::string appName ) 30 { 30 31 this->appName = appName; 31 32 … … 77 78 78 79 printf( "recieved signal %s\ntry to write backtrace to file orxonox.backtrace\n", sigName.c_str() ); 79 80 int fd[2]; 81 82 assert( pipe(fd) != -1 ); 83 84 int pid = fork(); 85 86 assert( pid != -1 ); 87 88 89 if ( pid == 0 ) 80 81 int sigPipe[2]; 82 if ( pipe(sigPipe) == -1 ) 83 { 84 perror("pipe failed!\n"); 85 exit(EXIT_FAILURE); 86 } 87 88 int sigPid = fork(); 89 90 if ( sigPid == -1 ) 91 { 92 perror("fork failed!\n"); 93 exit(EXIT_FAILURE); 94 } 95 96 // gdb will be attached to this process 97 if ( sigPid == 0 ) 90 98 { 91 99 getInstance()->dontCatch(); 92 sleep(2); 100 // wait for message from parent when it has attached gdb 101 int someData; 102 103 read( sigPipe[0], &someData, sizeof(someData) ); 104 105 if ( someData != 0x12345678 ) 106 { 107 printf("something went wrong :(\n"); 108 } 93 109 94 110 return; 95 111 } 96 else 97 { 98 getInstance()->dontCatch(); 99 if ( getInstance()->type == GDB_RUN_WRITE_TO_FILE && fork() == 0 ) 100 { 101 sleep(1); 102 write( fd[1], "c\nbt\nq\n", 7 ); 103 104 exit(0); 105 } 106 107 char command[256]; 108 if ( getInstance()->type == GDB_RUN_WRITE_TO_FILE ) 109 { 110 dup2( fd[0], STDIN_FILENO ); 111 snprintf( command, 255, "gdb -p %d %s 1>>" GDB_BT_FILE " 2>&1", pid, getInstance()->appName.c_str() ); 112 } 113 else 114 snprintf( command, 255, "gdb -p %d %s", pid, getInstance()->appName.c_str() ); 115 execlp( "sh", "sh", "-c", command, (void*)NULL); 116 } 112 113 int gdbIn[2]; 114 int gdbOut[2]; 115 int gdbErr[2]; 116 117 if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 ) 118 { 119 perror("pipe failed!\n"); 120 kill( sigPid, SIGTERM ); 121 waitpid( sigPid, NULL, 0 ); 122 exit(EXIT_FAILURE); 123 } 124 125 int gdbPid = fork(); 126 // this process will run gdb 127 128 if ( gdbPid == -1 ) 129 { 130 perror("fork failed\n"); 131 kill( sigPid, SIGTERM ); 132 waitpid( sigPid, NULL, 0 ); 133 exit(EXIT_FAILURE); 134 } 135 136 if ( gdbPid == 0 ) 137 { 138 // start gdb 139 140 close(gdbIn[1]); 141 close(gdbOut[0]); 142 close(gdbErr[0]); 143 144 dup2( gdbIn[0], STDIN_FILENO ); 145 dup2( gdbOut[1], STDOUT_FILENO ); 146 dup2( gdbErr[1], STDERR_FILENO ); 147 148 execlp( "sh", "sh", "-c", "gdb", (void*)NULL); 149 } 150 151 char cmd[256]; 152 snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance()->appName.c_str(), sigPid ); 153 write( gdbIn[1], cmd, strlen(cmd) ); 154 155 int charsFound = 0; 156 int promptFound = 0; 157 char byte; 158 while ( read( gdbOut[0], &byte, 1 ) == 1 ) 159 { 160 if ( 161 charsFound == 0 && byte == '(' || 162 charsFound == 1 && byte == 'g' || 163 charsFound == 2 && byte == 'd' || 164 charsFound == 3 && byte == 'b' || 165 charsFound == 4 && byte == ')' || 166 charsFound == 5 && byte == ' ' 167 ) 168 charsFound++; 169 170 if ( charsFound == 6 ) 171 { 172 promptFound++; 173 charsFound = 0; 174 } 175 176 if ( promptFound == 3 ) 177 { 178 break; 179 } 180 } 181 182 int someData = 0x12345678; 183 write( sigPipe[1], &someData, sizeof(someData) ); 184 185 write( gdbIn[1], "bt\nq\n", 5 ); 186 187 188 charsFound = 0; 189 promptFound = 0; 190 std::string bt; 191 while ( read( gdbOut[0], &byte, 1 ) == 1 ) 192 { 193 bt += std::string( &byte, 1 ); 194 195 if ( 196 charsFound == 0 && byte == '(' || 197 charsFound == 1 && byte == 'g' || 198 charsFound == 2 && byte == 'd' || 199 charsFound == 3 && byte == 'b' || 200 charsFound == 4 && byte == ')' || 201 charsFound == 5 && byte == ' ' 202 ) 203 charsFound++; 204 205 if ( charsFound == 6 ) 206 { 207 promptFound++; 208 charsFound = 0; 209 bt += "\n"; 210 } 211 212 if ( promptFound == 2 ) 213 { 214 break; 215 } 216 } 217 218 219 waitpid( sigPid, NULL, 0 ); 220 waitpid( gdbPid, NULL, 0 ); 221 222 int wsRemoved = 0; 223 224 while ( wsRemoved < 2 && bt.length() > 0 ) 225 { 226 if ( bt[1] == '\n' ) 227 wsRemoved++; 228 bt.erase(0, 1); 229 } 230 231 if ( bt.length() > 0 ) 232 bt.erase(0, 1); 233 234 time_t now = time(NULL); 235 236 std::string timeString = "\n\n\n\n" 237 "=======================================================\n" 238 "= time: " + std::string(ctime(&now)) + 239 "=======================================================\n"; 240 bt.insert(0, timeString); 241 242 FILE * f = fopen( GDB_BT_FILE, "a" ); 243 244 if ( !f ) 245 { 246 perror("could not append to " GDB_BT_FILE); 247 exit(EXIT_FAILURE); 248 } 249 250 if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() ) 251 { 252 printf("could not write %d byte to " GDB_BT_FILE, bt.length()); 253 exit(EXIT_FAILURE); 254 } 255 256 exit(EXIT_FAILURE); 117 257 } 118 258 -
trunk/src/util/signal_handler.h
r9110 r9240 12 12 13 13 #define GDB_BT_FILE "orxonox.backtrace" 14 enum GdbRunType{15 GDB_RUN_WRITE_TO_FILE = 1,16 GDB_RUN_IN_FOREGROUND17 };18 14 19 15 typedef int (*SignalCallback)( void * someData ); … … 48 44 void registerCallback( SignalCallback cb, void * someData ); 49 45 50 void doCatch( std::string appName , GdbRunType type = GDB_RUN_WRITE_TO_FILE);46 void doCatch( std::string appName ); 51 47 void dontCatch(); 52 48 … … 61 57 static SignalHandler * singletonRef; 62 58 63 GdbRunType type;64 65 59 std::string appName; 66 60 }; … … 71 65 public: 72 66 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }; 73 void doCatch( std::string appName , GdbRunType type = GDB_RUN_WRITE_TO_FILE) {};67 void doCatch( std::string appName ) {}; 74 68 void dontCatch() {}; 75 69 void registerCallback( SignalCallback cb, void * someData ) {};
Note: See TracChangeset
for help on using the changeset viewer.