blob: 341eb389384c4f33e5aec891c5204d0de087e1d8 [file] [log] [blame]
Kevin Holbrook95049ed1999-07-24 12:07:35 +00001/*
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
18
19#define DBG_BUFF_SIZE 12
20
21#define DBG_EXTERNAL_DEFAULT "gdb"
22#define DBG_LOCATION_DEFAULT "/usr/local/bin/wine"
23#define DBG_SLEEPTIME_DEFAULT 120
24
25
26
27/* DEBUG_ExternalDebugger
28 *
29 * This function invokes an external debugger on the current
30 * wine process. The form of the command executed is:
31 * <debugger image> <wine image> <attach process id>
32 *
33 * The debugger command is normally invoked by a newly created xterm.
34 *
35 * The current calling process is temporarily put to sleep
36 * so that the invoked debugger has time to come up and attach.
37 *
38 * The following environment variables may be used:
39 *
40 * Name Use Default
41 * -------------------------------------------------------------------------------------
42 * WINE_DBG_EXTERNAL debugger command to invoke ("gdb")
43 * WINE_DBG_LOCATION fully qualified location of wine image ("/usr/local/bin/wine")
44 * WINE_DBG_NO_XTERM if set do not invoke xterm with command (not set)
45 * WINE_DBG_SLEEPTIME number of seconds to make process sleep (120)
46 *
47 *
48 * Usage:
49 *
50 * #include "debugtools.h"
51 *
52 * DEBUG_ExternalDebugger();
53 *
54 *
55 * Environment Example:
56 *
57 * export WINE_DBG_EXTERNAL="ddd"
58 * export WINE_DBG_NO_XTERM=1
59 * export WINE_DBG_SLEEPTIME=60
60 *
61 */
62
63void DEBUG_ExternalDebugger(void)
64{
65 pid_t attach_pid;
66 pid_t child_pid;
67 int dbg_sleep_secs = DBG_SLEEPTIME_DEFAULT;
68 char *dbg_sleeptime;
69
70
71 dbg_sleeptime = getenv("WINE_DBG_SLEEPTIME");
72
73 /* convert sleep time string to integer seconds */
74 if (dbg_sleeptime)
75 {
76 dbg_sleep_secs = atoi(dbg_sleeptime);
77
78 /* check for conversion error */
79 if (dbg_sleep_secs == 0)
80 dbg_sleep_secs = DBG_SLEEPTIME_DEFAULT;
81 }
82
83 /* get the curent process id */
84 attach_pid = getpid();
85
86 /* create new process */
87 child_pid = fork();
88
89 /* check if we are the child process */
90 if (child_pid == 0)
91 {
92 int status;
93 char *dbg_external;
94 char *dbg_wine_location;
95 char *dbg_no_xterm;
96 char pid_string[DBG_BUFF_SIZE];
97
98
99 /* check settings in environment for debugger to use */
100 dbg_external = getenv("WINE_DBG_EXTERNAL");
101 dbg_wine_location = getenv("WINE_DBG_LOCATION");
102 dbg_no_xterm = getenv("WINE_DBG_NO_XTERM");
103
104 /* if not set in environment, use default */
105 if (!dbg_external)
106 dbg_external = "gdb";
107
108 /* if not set in environment, use default */
109 if (!dbg_wine_location)
110 dbg_wine_location = "/usr/local/bin/wine";
111
112 /* check for empty string in WINE_DBG_NO_XTERM */
113 if (dbg_no_xterm && (strlen(dbg_no_xterm) < 1))
114 dbg_no_xterm = NULL;
115
116 /* clear the buffer */
117 memset(pid_string, 0, DBG_BUFF_SIZE);
118
119 /* make pid into string */
120 sprintf(pid_string, "%d", attach_pid);
121
122 /* now exec the debugger to get it's own clean memory space */
123 if (dbg_no_xterm)
124 status = execlp(dbg_external, dbg_external, dbg_wine_location, pid_string, NULL);
125 else
126 status = execlp("xterm", "xterm", "-e", dbg_external, dbg_wine_location, pid_string, NULL);
127
128 if (status == -1)
129 {
130 if (dbg_no_xterm)
131 fprintf(stderr, "DEBUG_ExternalDebugger failed to execute \"%s %s %s\", errno = %d\n",
132 dbg_external, dbg_wine_location, pid_string, errno);
133 else
134 fprintf(stderr, "DEBUG_ExternalDebugger failed to execute \"xterm -e %s %s %s\", errno = %d\n",
135 dbg_external, dbg_wine_location, pid_string, errno);
136 }
137
138 }
139 else if (child_pid != -1)
140 {
141 /* make the parent/caller sleep so the child/debugger can catch it */
142 sleep(dbg_sleep_secs);
143 }
144 else
145 fprintf(stderr, "DEBUG_ExternalDebugger failed.\n");
146
147}
148
149