Complete.Org: Mailing Lists: Archives: freeciv-dev: September 2004:
[Freeciv-Dev] (PR#10282) internal civserver run inside gdb
Home

[Freeciv-Dev] (PR#10282) internal civserver run inside gdb

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: undisclosed-recipients: ;
Subject: [Freeciv-Dev] (PR#10282) internal civserver run inside gdb
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Thu, 23 Sep 2004 12:15:30 -0700
Reply-to: rt@xxxxxxxxxxx

<URL: http://rt.freeciv.org/Ticket/Display.html?id=10282 >

With this patch civclient runs it's internal civserver through gdb.
Backtrace is displayed in chat window, if server crashes.
This is of course not intended for commit.
(If I added runtime gdb detection, who knows)
To test it run a simple game, set timeout to -1 and type 
'killall -11 civserver' in console.
--
mateusz

? civgame-3000.sav.gz
? civgame-3500.sav.gz
? civgame-3950.sav.gz
? core.16019
? gdb_script
Index: clinet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/clinet.c,v
retrieving revision 1.100
diff -u -r1.100 clinet.c
--- clinet.c    20 Jul 2004 17:13:52 -0000      1.100
+++ clinet.c    23 Sep 2004 19:12:09 -0000
@@ -74,6 +74,7 @@
 #include "chatline_g.h"
 #include "civclient.h"
 #include "climisc.h"
+#include "connectdlg_common.h"
 #include "connectdlg_g.h"
 #include "dialogs_g.h"         /* popdown_races_dialog() */
 #include "gui_main_g.h"                /* add_net_input(), remove_net_input() 
*/
@@ -119,6 +120,7 @@
   append_output_window(_("Lost connection to server!"));
   freelog(LOG_NORMAL, "lost connection to server");
   close_socket_nomessage(pc);
+  client_kill_server();
 }
 
 /**************************************************************************
Index: connectdlg_common.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/client/connectdlg_common.c,v
retrieving revision 1.23
diff -u -r1.23 connectdlg_common.c
--- connectdlg_common.c 18 Sep 2004 17:47:28 -0000      1.23
+++ connectdlg_common.c 23 Sep 2004 19:12:10 -0000
@@ -124,6 +124,8 @@
   return client_has_hack;
 }
 
+static int client_gdb[2];
+static int gdb_client[2];
 /************************************************************************** 
 Kills the server if the client has started it.
 **************************************************************************/ 
@@ -139,6 +141,13 @@
     server_process = INVALID_HANDLE_VALUE;
     loghandle = INVALID_HANDLE_VALUE;
 #else
+    char buf[50000];
+    append_output_window("Internal server killed. Gdb output:");
+    int l = read(gdb_client[0], buf, 50000);
+    if (l != -1) {
+      buf[l] = '\0';
+    }
+    append_output_window(buf);
     kill(server_pid, SIGTERM);
     waitpid(server_pid, NULL, WUNTRACED);
     server_pid = - 1;
@@ -155,6 +164,7 @@
   client_kill_server();
 }
                                                                                
+
 /**************************************************************** 
 forks a server if it can. returns FALSE is we find we couldn't start
 the server.
@@ -197,66 +207,34 @@
   internal_server_port = find_next_free_port(DEFAULT_SOCK_PORT);
 
 # ifdef HAVE_WORKING_FORK
+
+  pipe(client_gdb);
+  pipe(gdb_client);
+  FILE* gdb_script = fopen("gdb_script", "w+");
+  fprintf(gdb_script, "run -p %d -q 3 -e >/dev/null\nbacktrace\nquit\n\n", 
internal_server_port);
+  fclose(gdb_script);
+  
   server_pid = fork();
   
   if (server_pid == 0) {
-    int fd, argc = 0;
     const int max_nargs = 13;
-    char *argv[max_nargs + 1], port_buf[32];
-
-    /* inside the child */
-
-    /* Set up the command-line parameters. */
-    my_snprintf(port_buf, sizeof(port_buf), "%d", internal_server_port);
-    argv[argc++] = "civserver";
-    argv[argc++] = "-p";
-    argv[argc++] = port_buf;
-    argv[argc++] = "-q";
-    argv[argc++] = "1";
-    argv[argc++] = "-e";
-    if (logfile) {
-      argv[argc++] = "--debug";
-      argv[argc++] = "3";
-      argv[argc++] = "--log";
-      argv[argc++] = logfile;
-    }
-    if (scriptfile) {
-      argv[argc++] = "--read";
-      argv[argc++] = scriptfile;
-    }
-    argv[argc] = NULL;
-    assert(argc <= max_nargs);
-
-    /* avoid terminal spam, but still make server output available */ 
-    fclose(stdout);
-    fclose(stderr);
-
-    /* include the port to avoid duplication */
-    if (logfile) {
-      fd = open(logfile, O_WRONLY | O_CREAT);
-
-      if (fd != 1) {
-        dup2(fd, 1);
-      }
-      if (fd != 2) {
-        dup2(fd, 2);
-      }
-      fchmod(1, 0644);
-    }
-
-    /* If it's still attatched to our terminal, things get messed up, 
-      but civserver needs *something* */ 
-    fclose(stdin);
-    fd = open("/dev/null", O_RDONLY);
-    if (fd != 0) {
-      dup2(fd, 0);
-    }
-
-    /* these won't return on success */ 
-    execvp("./ser", argv);
-    execvp("./server/civserver", argv);
-    execvp("civserver", argv);
+    char *argv[max_nargs + 1];
     
+    dup2(client_gdb[0], 0);
+    dup2(gdb_client[1], 1);
+    close(2);
+    close(client_gdb[0]);
+    close(client_gdb[1]);    
+    close(gdb_client[0]);
+    close(gdb_client[1]);
+    argv[0] = "gdb";
+    argv[1] = "civserver";
+    argv[2] = "-x";
+    argv[3] = "gdb_script";
+    argv[4] = "-q";
+    argv[5] = NULL;
+    execvp("gdb", argv);
+
     /* This line is only reached if civserver cannot be started, 
      * so we kill the forked process.
      * Calling exit here is dangerous due to X11 problems (async replies) */ 
@@ -313,7 +291,7 @@
 
 #  endif
 # endif
- 
+
   /* a reasonable number of tries */ 
   while (connect_to_server(user_name, "localhost", internal_server_port, 
                            buf, sizeof(buf)) == -1) {

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#10282) internal civserver run inside gdb, Mateusz Stefek <=