/* Target-vector operations for controlling win32 child processes, for GDB.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006
- Free Software Foundation, Inc.
+ 2005, 2006, 2007 Free Software Foundation, Inc.
Contributed by Cygnus Solutions, A Red Hat Company.
/* User options. */
static int new_console = 0;
+static int cygwin_exceptions = 0;
static int new_group = 1;
static int debug_exec = 0; /* show execution */
static int debug_events = 0; /* show events from kernel */
}
static void
-do_win32_fetch_inferior_registers (int r)
+do_win32_fetch_inferior_registers (struct regcache *regcache, int r)
{
char *context_offset = ((char *) ¤t_thread->context) + mappings[r];
long l;
if (r == I387_FISEG_REGNUM)
{
l = *((long *) context_offset) & 0xffff;
- regcache_raw_supply (current_regcache, r, (char *) &l);
+ regcache_raw_supply (regcache, r, (char *) &l);
}
else if (r == I387_FOP_REGNUM)
{
l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
- regcache_raw_supply (current_regcache, r, (char *) &l);
+ regcache_raw_supply (regcache, r, (char *) &l);
}
else if (r >= 0)
- regcache_raw_supply (current_regcache, r, context_offset);
+ regcache_raw_supply (regcache, r, context_offset);
else
{
- for (r = 0; r < NUM_REGS; r++)
- do_win32_fetch_inferior_registers (r);
+ for (r = 0; r < gdbarch_num_regs (current_gdbarch); r++)
+ do_win32_fetch_inferior_registers (regcache, r);
}
#undef I387_ST0_REGNUM
}
static void
-win32_fetch_inferior_registers (int r)
+win32_fetch_inferior_registers (struct regcache *regcache, int r)
{
current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
/* Check if current_thread exists. Windows sometimes uses a non-existent
thread id in its events */
if (current_thread)
- do_win32_fetch_inferior_registers (r);
+ do_win32_fetch_inferior_registers (regcache, r);
}
static void
-do_win32_store_inferior_registers (int r)
+do_win32_store_inferior_registers (const struct regcache *regcache, int r)
{
if (!current_thread)
/* Windows sometimes uses a non-existent thread id in its events */;
else if (r >= 0)
- regcache_raw_collect (current_regcache, r,
+ regcache_raw_collect (regcache, r,
((char *) ¤t_thread->context) + mappings[r]);
else
{
- for (r = 0; r < NUM_REGS; r++)
- do_win32_store_inferior_registers (r);
+ for (r = 0; r < gdbarch_num_regs (current_gdbarch); r++)
+ do_win32_store_inferior_registers (regcache, r);
}
}
/* Store a new register value into the current thread context */
static void
-win32_store_inferior_registers (int r)
+win32_store_inferior_registers (struct regcache *regcache, int r)
{
current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
/* Check if current_thread exists. Windows sometimes uses a non-existent
thread id in its events */
if (current_thread)
- do_win32_store_inferior_registers (r);
+ do_win32_store_inferior_registers (regcache, r);
}
static int psapi_loaded = 0;
within the text segment of the DLL itself. */
char *fn;
bfd_vma addr = (bfd_vma) current_event.u.Exception.ExceptionRecord.ExceptionAddress;
- if ((addr >= cygwin_load_start && addr < cygwin_load_end)
+ if ((!cygwin_exceptions && (addr >= cygwin_load_start && addr < cygwin_load_end))
|| (find_pc_partial_function (addr, &fn, NULL, NULL)
&& strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0))
return 0;
if (step)
{
/* Single step by setting t bit */
- win32_fetch_inferior_registers (PS_REGNUM);
+ win32_fetch_inferior_registers (get_current_regcache (),
+ gdbarch_ps_regnum (current_gdbarch));
th->context.EFlags |= FLAG_TRACE_BIT;
}
{
int pid = PIDGET (ptid);
+ target_terminal_ours ();
+
/* We loop when we get a non-standard exception rather than return
with a SPURIOUS because resume can try and step or modify things,
which needs a current_thread->h. But some of these exceptions mark
clear_proceed_status ();
init_wait_for_inferior ();
- target_terminal_init ();
+ terminal_init_inferior_with_pgrp (pid);
target_terminal_inferior ();
while (1)
if (has_detach_ability ())
{
- delete_command (NULL, 0);
- win32_continue (DBG_CONTINUE, -1);
+ ptid_t ptid = {-1};
+ win32_resume (ptid, 0, TARGET_SIGNAL_0);
+
if (!DebugActiveProcessStop (current_event.dwProcessId))
{
error (_("Can't detach process %lu (error %lu)"),
error (_("Use the \"run\" command to start a Unix child process."));
}
-/* Function called by qsort to sort environment strings. */
-static int
-env_sort (const void *a, const void *b)
-{
- const char **p = (const char **) a;
- const char **q = (const char **) b;
- return strcasecmp (*p, *q);
-}
-
/* Start an inferior win32 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.
win32_create_inferior (char *exec_file, char *allargs, char **in_env,
int from_tty)
{
- char *winenv;
- char *temp;
- int envlen;
- int i;
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL ret;
strcat (args, allargs);
/* Prepare the environment vars for CreateProcess. */
- {
- /* This code used to assume all env vars were file names and would
- translate them all to win32 style. That obviously doesn't work in the
- general case. The current rule is that we only translate PATH.
- We need to handle PATH because we're about to call CreateProcess and
- it uses PATH to find DLL's. Fortunately PATH has a well-defined value
- in both posix and win32 environments. cygwin.dll will change it back
- to posix style if necessary. */
-
- static const char *conv_path_names[] =
- {
- "PATH=",
- 0
- };
-
- /* CreateProcess takes the environment list as a null terminated set of
- strings (i.e. two nulls terminate the list). */
-
- /* Get total size for env strings. */
- for (envlen = 0, i = 0; in_env[i] && *in_env[i]; i++)
- {
- int j, len;
-
- for (j = 0; conv_path_names[j]; j++)
- {
- len = strlen (conv_path_names[j]);
- if (strncmp (conv_path_names[j], in_env[i], len) == 0)
- {
- if (cygwin_posix_path_list_p (in_env[i] + len))
- envlen += len
- + cygwin_posix_to_win32_path_list_buf_size (in_env[i] + len);
- else
- envlen += strlen (in_env[i]) + 1;
- break;
- }
- }
- if (conv_path_names[j] == NULL)
- envlen += strlen (in_env[i]) + 1;
- }
-
- size_t envsize = sizeof (in_env[0]) * (i + 1);
- char **env = (char **) alloca (envsize);
- memcpy (env, in_env, envsize);
- /* Windows programs expect the environment block to be sorted. */
- qsort (env, i, sizeof (char *), env_sort);
-
- winenv = alloca (envlen + 1);
-
- /* Copy env strings into new buffer. */
- for (temp = winenv, i = 0; env[i] && *env[i]; i++)
- {
- int j, len;
-
- for (j = 0; conv_path_names[j]; j++)
- {
- len = strlen (conv_path_names[j]);
- if (strncmp (conv_path_names[j], env[i], len) == 0)
- {
- if (cygwin_posix_path_list_p (env[i] + len))
- {
- memcpy (temp, env[i], len);
- cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
- }
- else
- strcpy (temp, env[i]);
- break;
- }
- }
- if (conv_path_names[j] == NULL)
- strcpy (temp, env[i]);
-
- temp += strlen (temp) + 1;
- }
-
- /* Final nil string to terminate new env. */
- *temp = 0;
- }
+ cygwin_internal (CW_SYNC_WINENV);
if (!inferior_io_terminal)
tty = ostdin = ostdout = ostderr = -1;
NULL, /* thread */
TRUE, /* inherit handles */
flags, /* start flags */
- winenv,
+ NULL, /* environment */
NULL, /* current directory */
&si,
&pi);
}
static void
-win32_prepare_to_store (void)
+win32_prepare_to_store (struct regcache *regcache)
{
/* Do nothing, since we can store individual regs */
}
}
static void
-fetch_elf_core_registers (char *core_reg_sect,
+fetch_elf_core_registers (struct regcache *regcache,
+ char *core_reg_sect,
unsigned core_reg_size,
int which,
CORE_ADDR reg_addr)
error (_("Core file register section too small (%u bytes)."), core_reg_size);
return;
}
- for (r = 0; r < NUM_REGS; r++)
- regcache_raw_supply (current_regcache, r, core_reg_sect + mappings[r]);
+ for (r = 0; r < gdbarch_num_regs (current_gdbarch); r++)
+ regcache_raw_supply (regcache, r, core_reg_sect + mappings[r]);
}
static int
NULL, /* FIXME: i18n: */
&setlist, &showlist);
+ add_setshow_boolean_cmd ("cygwin-exceptions", class_support, &cygwin_exceptions, _("\
+Break when an exception is detected in the Cygwin DLL itself."), _("\
+Show whether gdb breaks on exceptions in the Cygwin DLL itself."), NULL,
+ NULL,
+ NULL, /* FIXME: i18n: */
+ &setlist, &showlist);
+
add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
Set creation of new console when creating child process."), _("\
Show creation of new console when creating child process."), NULL,