Added support for nested server waits (to allow waiting in signal
[wine/multimedia.git] / debugger / ext_debugger.c
blob124ca26d8d987590d88479e095776244a447e793
1 /*
2 * File : external.c
3 * Author : Kevin Holbrook
4 * Created : July 18, 1999
6 * Convenience functions to handle use of external debugger.
8 */
11 #include <unistd.h>
12 #include <errno.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
17 #define DBG_BUFF_SIZE 12
19 #define DBG_EXTERNAL_DEFAULT "gdb"
20 #define DBG_LOCATION_DEFAULT "/usr/local/bin/wine"
21 #define DBG_SLEEPTIME_DEFAULT 120
25 /* DEBUG_ExternalDebugger
27 * This function invokes an external debugger on the current
28 * wine process. The form of the command executed is:
29 * <debugger image> <wine image> <attach process id>
31 * The debugger command is normally invoked by a newly created xterm.
33 * The current calling process is temporarily put to sleep
34 * so that the invoked debugger has time to come up and attach.
36 * The following environment variables may be used:
38 * Name Use Default
39 * -------------------------------------------------------------------------------------
40 * WINE_DBG_EXTERNAL debugger command to invoke ("gdb")
41 * WINE_DBG_LOCATION fully qualified location of wine image ("/usr/local/bin/wine")
42 * WINE_DBG_NO_XTERM if set do not invoke xterm with command (not set)
43 * WINE_DBG_SLEEPTIME number of seconds to make process sleep (120)
46 * Usage:
48 * #include "debugtools.h"
50 * DEBUG_ExternalDebugger();
53 * Environment Example:
55 * export WINE_DBG_EXTERNAL="ddd"
56 * export WINE_DBG_NO_XTERM=1
57 * export WINE_DBG_SLEEPTIME=60
61 void DEBUG_ExternalDebugger(void)
63 pid_t attach_pid;
64 pid_t child_pid;
65 int dbg_sleep_secs = DBG_SLEEPTIME_DEFAULT;
66 char *dbg_sleeptime;
69 dbg_sleeptime = getenv("WINE_DBG_SLEEPTIME");
71 /* convert sleep time string to integer seconds */
72 if (dbg_sleeptime)
74 dbg_sleep_secs = atoi(dbg_sleeptime);
76 /* check for conversion error */
77 if (dbg_sleep_secs == 0)
78 dbg_sleep_secs = DBG_SLEEPTIME_DEFAULT;
81 /* get the curent process id */
82 attach_pid = getpid();
84 /* create new process */
85 child_pid = fork();
87 /* check if we are the child process */
88 if (child_pid == 0)
90 int status;
91 const char *dbg_external;
92 const char *dbg_wine_location;
93 const char *dbg_no_xterm;
94 char pid_string[DBG_BUFF_SIZE];
97 /* check settings in environment for debugger to use */
98 dbg_external = getenv("WINE_DBG_EXTERNAL");
99 dbg_wine_location = getenv("WINE_DBG_LOCATION");
100 dbg_no_xterm = getenv("WINE_DBG_NO_XTERM");
102 /* if not set in environment, use default */
103 if (!dbg_external)
104 dbg_external = "gdb";
106 /* if not set in environment, use default */
107 if (!dbg_wine_location)
108 dbg_wine_location = "wine";
110 /* check for empty string in WINE_DBG_NO_XTERM */
111 if (dbg_no_xterm && (strlen(dbg_no_xterm) < 1))
112 dbg_no_xterm = NULL;
114 /* clear the buffer */
115 memset(pid_string, 0, DBG_BUFF_SIZE);
117 /* make pid into string */
118 sprintf(pid_string, "%ld", (long) attach_pid);
120 /* now exec the debugger to get it's own clean memory space */
121 if (dbg_no_xterm)
122 status = execlp(dbg_external, dbg_external, dbg_wine_location, pid_string, NULL);
123 else
124 status = execlp("xterm", "xterm", "-e", dbg_external, dbg_wine_location, pid_string, NULL);
126 if (status == -1)
128 if (dbg_no_xterm)
129 fprintf(stderr, "DEBUG_ExternalDebugger failed to execute \"%s %s %s\" (%s)\n",
130 dbg_external, dbg_wine_location, pid_string, strerror(errno));
131 else
132 fprintf(stderr, "DEBUG_ExternalDebugger failed to execute \"xterm -e %s %s %s\" (%s)\n",
133 dbg_external, dbg_wine_location, pid_string, strerror(errno));
137 else if (child_pid != -1)
139 /* make the parent/caller sleep so the child/debugger can catch it */
140 sleep(dbg_sleep_secs);
142 else
143 fprintf(stderr, "DEBUG_ExternalDebugger failed.\n");