#include <imagehlp.h>
#include <psapi.h>
#ifdef __CYGWIN__
+#include <wchar.h>
#include <sys/cygwin.h>
+#include <cygwin/version.h>
#endif
#include <signal.h>
}
#endif
+#ifdef __CYGWIN__
+static void
+clear_win32_environment (char **env)
+{
+ int i;
+ size_t len;
+ wchar_t *copy = NULL, *equalpos;
+
+ for (i = 0; env[i] && *env[i]; i++)
+ {
+ len = mbstowcs (NULL, env[i], 0) + 1;
+ copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t));
+ mbstowcs (copy, env[i], len);
+ equalpos = wcschr (copy, L'=');
+ if (equalpos)
+ *equalpos = L'\0';
+ SetEnvironmentVariableW (copy, NULL);
+ }
+ xfree (copy);
+}
+#endif
+
/* Start an inferior windows child process and sets inferior_ptid to its pid.
EXEC_FILE is the file to run.
ALLARGS is a string containing the arguments to the program.
cygwin_buf_t *toexec;
cygwin_buf_t *cygallargs;
cygwin_buf_t *args;
+ char **old_env = NULL;
+ PWCHAR w32_env;
size_t len;
int tty;
int ostdin, ostdout, ostderr;
strcat (args, cygallargs);
#endif
- /* Prepare the environment vars for CreateProcess. */
- cygwin_internal (CW_SYNC_WINENV);
+#ifdef CW_CVT_ENV_TO_WINENV
+ /* First try to create a direct Win32 copy of the POSIX environment. */
+ w32_env = (PWCHAR) cygwin_internal (CW_CVT_ENV_TO_WINENV, in_env);
+ if (w32_env != (PWCHAR) -1)
+ flags |= CREATE_UNICODE_ENVIRONMENT;
+ else
+ /* If that fails, fall back to old method tweaking GDB's environment. */
+#endif
+ {
+ /* Reset all Win32 environment variables to avoid leftover on next run. */
+ clear_win32_environment (environ);
+ /* Prepare the environment vars for CreateProcess. */
+ old_env = environ;
+ environ = in_env;
+ cygwin_internal (CW_SYNC_WINENV);
+ w32_env = NULL;
+ }
if (!inferior_io_terminal)
tty = ostdin = ostdout = ostderr = -1;
NULL, /* thread */
TRUE, /* inherit handles */
flags, /* start flags */
- NULL, /* environment */
+ w32_env, /* environment */
NULL, /* current directory */
&si,
&pi);
+ if (w32_env)
+ /* Just free the Win32 environment, if it could be created. */
+ free (w32_env);
+ else
+ {
+ /* Reset all environment variables to avoid leftover on next run. */
+ clear_win32_environment (in_env);
+ /* Restore normal GDB environment variables. */
+ environ = old_env;
+ cygwin_internal (CW_SYNC_WINENV);
+ }
+
if (tty >= 0)
{
close (tty);
i386_dr_low.set_control = cygwin_set_dr7;
i386_dr_low.set_addr = cygwin_set_dr;
- i386_dr_low.reset_addr = NULL;
+ i386_dr_low.get_addr = cygwin_get_dr;
i386_dr_low.get_status = cygwin_get_dr6;
+ i386_dr_low.get_control = cygwin_get_dr7;
/* i386_dr_low.debug_register_length field is set by
calling i386_set_debug_register_length function
debug_registers_used = 1;
}
+/* Get the value of debug register I from the inferior. */
+
+static CORE_ADDR
+cygwin_get_dr (int i)
+{
+ return dr[i];
+}
+
/* Get the value of the DR6 debug status register from the inferior.
Here we just return the value stored in dr[6]
by the last call to thread_rec for current_event.dwThreadId id. */
return (unsigned long) dr[6];
}
+/* Get the value of the DR7 debug status register from the inferior.
+ Here we just return the value stored in dr[7] by the last call to
+ thread_rec for current_event.dwThreadId id. */
+
+static unsigned long
+cygwin_get_dr7 (void)
+{
+ return (unsigned long) dr[7];
+}
+
/* Determine if the thread referenced by "ptid" is alive
by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
it means that the thread has died. Otherwise it is assumed to be alive. */