3 Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
23 /* Here lies extra debugging routines which help track down internal
24 Cygwin problems when compiled with -DDEBUGGING . */
25 #define NFREEH (sizeof (cygheap->debug.freeh) / sizeof (cygheap->debug.freeh[0]))
33 locker.acquire (INFINITE);
39 ~lock_debug () {unlock ();}
40 friend void debug_init ();
43 muto NO_COPY lock_debug::locker;
45 static bool __stdcall mark_closed (const char *, int, HANDLE, const char *, bool);
50 lock_debug::locker.init ("debug_lock");
53 /* Find a registered handle in the linked list of handles. */
54 static handle_list * __stdcall
55 find_handle (HANDLE h)
58 for (hl = &cygheap->debug.starth; hl->next != NULL; hl = hl->next)
68 verify_handle (const char *func, int ln, HANDLE h)
71 handle_list *hl = find_handle (h);
74 system_printf ("%s:%d - multiple attempts to add handle %p", func, ln, h);
76 system_printf (" previously allocated by %s:%d(%s<%p>) winpid %d",
77 hl->func, hl->ln, hl->name, hl->h, hl->pid);
81 setclexec (HANDLE oh, HANDLE nh, bool not_inheriting)
84 handle_list *hl = find_handle (oh);
88 hl->inherited = !not_inheriting;
93 /* Create a new handle record */
94 static handle_list * __stdcall
99 for (hl = cygheap->debug.freeh; hl < cygheap->debug.freeh + NFREEH; hl++)
100 if (hl->name == NULL)
107 modify_handle (const char *func, int ln, HANDLE h, const char *name, bool inh)
110 handle_list *hl = find_handle (h);
113 system_printf ("%s:%d handle %s<%p> not found", func, ln, name, h);
116 hl->next->inherited = inh;
117 debug_printf ("%s:%d set handle %s<%p> inheritance flag to %d", func, ln,
121 /* Add a handle to the linked list of known handles. */
123 add_handle (const char *func, int ln, HANDLE h, const char *name, bool inh)
131 if ((hl = find_handle (h)))
134 if (hl->name == name && hl->func == func && hl->ln == ln)
136 system_printf ("%s:%d - multiple attempts to add handle %s<%p>", func,
138 system_printf (" previously allocated by %s:%d(%s<%p>) winpid %d",
139 hl->func, hl->ln, hl->name, hl->h, hl->pid);
143 if ((hl = newh ()) == NULL)
146 debug_printf ("couldn't allocate memory for %s(%d): %s(%p)",
155 hl->pid = GetCurrentProcessId ();
156 hl->next = cygheap->debug.starth.next;
157 cygheap->debug.starth.next = hl;
158 SetHandleInformation (h, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE);
159 debug_printf ("protecting handle '%s'(%p), inherited flag %d", hl->name, hl->h, hl->inherited);
162 static void __stdcall
163 delete_handle (handle_list *hl)
165 handle_list *hnuke = hl->next;
166 debug_printf ("nuking handle '%s' (%p)", hnuke->name, hnuke->h);
167 hl->next = hnuke->next;
168 memset (hnuke, 0, sizeof (*hnuke));
172 debug_fixup_after_fork_exec ()
174 debug_printf ("BEFORE");
175 /* No lock needed at this point */
177 for (hl = &cygheap->debug.starth; hl->next != NULL; /* nothing */)
178 if (hl->next->inherited)
181 delete_handle (hl); // removes hl->next
182 debug_printf ("AFTER");
185 static bool __stdcall
186 mark_closed (const char *func, int ln, HANDLE h, const char *name, bool force)
193 if ((hl = find_handle (h)) && !force)
196 system_printf ("attempt to close protected handle %s:%d(%s<%p>) winpid %d",
197 hl->func, hl->ln, hl->name, hl->h, hl->pid);
198 system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
203 if (hl && (hln = hl->next) && strcmp (name, hln->name) != 0)
205 system_printf ("closing protected handle %s:%d(%s<%p>)",
206 hln->func, hln->ln, hln->name, hln->h);
207 system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
216 /* Close a known handle. Complain if !force and closing a known handle or
217 if the name of the handle being closed does not match the registered name. */
219 close_handle (const char *func, int ln, HANDLE h, const char *name, bool force)
224 if (!mark_closed (func, ln, h, name, force))
227 SetHandleInformation (h, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
228 ret = CloseHandle (h);
232 system_printf ("CloseHandle(%s<%p>) failed %s:%d, %E", name, h, func, ln);