Generalize the Wine version resource template a bit.
[wine] / debugger / ext_debugger.c
1 /* 
2  *  File    : external.c
3  *  Author  : Kevin Holbrook
4  *  Created : July 18, 1999
5  *
6  *  Convenience functions to handle use of external debugger.
7  *
8  */
9
10
11 #include <unistd.h>
12 #include <errno.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <string.h>
16
17 #define DBG_BUFF_SIZE  12
18
19 #define DBG_EXTERNAL_DEFAULT   "gdb"
20 #define DBG_LOCATION_DEFAULT   "/usr/local/bin/wine"
21 #define DBG_SLEEPTIME_DEFAULT  120
22
23
24
25 /* DEBUG_ExternalDebugger
26  *
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>
30  *
31  * The debugger command is normally invoked by a newly created xterm.
32  *
33  * The current calling process is temporarily put to sleep
34  * so that the invoked debugger has time to come up and attach.
35  *
36  * The following environment variables may be used:
37  *
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)
44  *
45  *
46  * Usage:
47  *
48  *   #include "debugtools.h"
49  *
50  *   DEBUG_ExternalDebugger();
51  *
52  *
53  * Environment Example:
54  *
55  *   export WINE_DBG_EXTERNAL="ddd"
56  *   export WINE_DBG_NO_XTERM=1
57  *   export WINE_DBG_SLEEPTIME=60
58  *
59  */
60
61 void DEBUG_ExternalDebugger(void)
62 {
63   pid_t attach_pid;
64   pid_t child_pid;
65   int   dbg_sleep_secs = DBG_SLEEPTIME_DEFAULT;
66   char *dbg_sleeptime;
67
68
69   dbg_sleeptime = getenv("WINE_DBG_SLEEPTIME");
70
71   /* convert sleep time string to integer seconds */
72   if (dbg_sleeptime)
73   {
74     dbg_sleep_secs = atoi(dbg_sleeptime);
75
76     /* check for conversion error */
77     if (dbg_sleep_secs == 0)
78       dbg_sleep_secs = DBG_SLEEPTIME_DEFAULT;
79   }
80
81   /* get the curent process id */
82   attach_pid = getpid();
83
84   /* create new process */
85   child_pid = fork();
86
87   /* check if we are the child process */
88   if (child_pid == 0)
89   {
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];    
95
96
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");
101
102     /* if not set in environment, use default */
103     if (!dbg_external)
104       dbg_external = "gdb";
105
106     /* if not set in environment, use default */
107     if (!dbg_wine_location)
108       dbg_wine_location = "wine";
109
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;
113
114     /* clear the buffer */
115     memset(pid_string, 0, DBG_BUFF_SIZE);
116
117     /* make pid into string */
118     sprintf(pid_string, "%ld", (long) attach_pid);
119
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); 
125
126     if (status == -1)
127     {
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));
134     }
135
136   }
137   else if (child_pid != -1)
138   {
139     /* make the parent/caller sleep so the child/debugger can catch it */
140     sleep(dbg_sleep_secs);
141   }
142   else
143     fprintf(stderr, "DEBUG_ExternalDebugger failed.\n");
144   
145 }
146
147