OSDN Git Service

* exceptions.cc (set_signal_mask): Remove useless debugging output.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / debug.cc
1 /* debug.cc
2
3    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4    2008, 2009, 2011
5    Red Hat, Inc.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include "cygerrno.h"
13 #ifdef DEBUGGING
14 #include "path.h"
15 #include "fhandler.h"
16 #include "dtable.h"
17 #include "cygheap.h"
18 #endif
19
20 #undef CloseHandle
21
22 #ifdef DEBUGGING
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]))
26
27 class lock_debug
28 {
29   static muto locker;
30  public:
31   lock_debug ()
32   {
33     locker.acquire (INFINITE);
34   }
35   void unlock ()
36   {
37     locker.release ();
38   }
39   ~lock_debug () {unlock ();}
40   friend void debug_init ();
41 };
42
43 muto NO_COPY lock_debug::locker;
44
45 static bool __stdcall mark_closed (const char *, int, HANDLE, const char *, bool);
46
47 void
48 debug_init ()
49 {
50   lock_debug::locker.init ("debug_lock");
51 }
52
53 /* Find a registered handle in the linked list of handles. */
54 static handle_list * __stdcall
55 find_handle (HANDLE h)
56 {
57   handle_list *hl;
58   for (hl = &cygheap->debug.starth; hl->next != NULL; hl = hl->next)
59     if (hl->next->h == h)
60       goto out;
61   hl = NULL;
62
63 out:
64   return hl;
65 }
66
67 void
68 verify_handle (const char *func, int ln, HANDLE h)
69 {
70   lock_debug here;
71   handle_list *hl = find_handle (h);
72   if (!hl)
73     return;
74   system_printf ("%s:%d - multiple attempts to add handle %p", func, ln, h);
75
76   system_printf (" previously allocated by %s:%d(%s<%p>) winpid %d",
77                  hl->func, hl->ln, hl->name, hl->h, hl->pid);
78 }
79
80 void
81 setclexec (HANDLE oh, HANDLE nh, bool not_inheriting)
82 {
83   lock_debug here;
84   handle_list *hl = find_handle (oh);
85   if (hl)
86     {
87       hl = hl->next;
88       hl->inherited = !not_inheriting;
89       hl->h = nh;
90     }
91 }
92
93 /* Create a new handle record */
94 static handle_list * __stdcall
95 newh ()
96 {
97   handle_list *hl;
98
99   for (hl = cygheap->debug.freeh; hl < cygheap->debug.freeh + NFREEH; hl++)
100     if (hl->name == NULL)
101       return hl;
102
103   return NULL;
104 }
105
106 void __stdcall
107 modify_handle (const char *func, int ln, HANDLE h, const char *name, bool inh)
108 {
109   lock_debug here;
110   handle_list *hl = find_handle (h);
111   if (!hl)
112     {
113       system_printf ("%s:%d handle %s<%p> not found", func, ln, name, h);
114       return;
115     }
116   hl->next->inherited = inh;
117   debug_printf ("%s:%d set handle %s<%p> inheritance flag to %d", func, ln,
118                 name, h, inh);
119 }
120
121 /* Add a handle to the linked list of known handles. */
122 void __stdcall
123 add_handle (const char *func, int ln, HANDLE h, const char *name, bool inh)
124 {
125   handle_list *hl;
126
127   if (!cygheap)
128     return;
129
130   lock_debug here;
131   if ((hl = find_handle (h)))
132     {
133       hl = hl->next;
134       if (hl->name == name && hl->func == func && hl->ln == ln)
135         return;
136       system_printf ("%s:%d - multiple attempts to add handle %s<%p>", func,
137                      ln, name, h);
138       system_printf (" previously allocated by %s:%d(%s<%p>) winpid %d",
139                      hl->func, hl->ln, hl->name, hl->h, hl->pid);
140       return;
141     }
142
143   if ((hl = newh ()) == NULL)
144     {
145       here.unlock ();
146       debug_printf ("couldn't allocate memory for %s(%d): %s(%p)",
147                     func, ln, name, h);
148       return;
149     }
150   hl->h = h;
151   hl->name = name;
152   hl->func = func;
153   hl->ln = ln;
154   hl->inherited = inh;
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);
160 }
161
162 static void __stdcall
163 delete_handle (handle_list *hl)
164 {
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));
169 }
170
171 void
172 debug_fixup_after_fork_exec ()
173 {
174   /* No lock needed at this point */
175   handle_list *hl;
176   for (hl = &cygheap->debug.starth; hl->next != NULL; /* nothing */)
177     if (hl->next->inherited)
178       hl = hl->next;
179     else
180       delete_handle (hl);       // removes hl->next
181 }
182
183 static bool __stdcall
184 mark_closed (const char *func, int ln, HANDLE h, const char *name, bool force)
185 {
186   handle_list *hl;
187
188   if (!cygheap)
189     return true;
190
191   if ((hl = find_handle (h)) && !force)
192     {
193       hl = hl->next;
194       system_printf ("attempt to close protected handle %s:%d(%s<%p>) winpid %d",
195                      hl->func, hl->ln, hl->name, hl->h, hl->pid);
196       system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
197       return false;
198     }
199
200   handle_list *hln;
201   if (hl && (hln = hl->next) && strcmp (name, hln->name) != 0)
202     {
203       system_printf ("closing protected handle %s:%d(%s<%p>)",
204                      hln->func, hln->ln, hln->name, hln->h);
205       system_printf (" by %s:%d(%s<%p>)", func, ln, name, h);
206     }
207
208   if (hl)
209     delete_handle (hl);
210
211   return true;
212 }
213
214 /* Close a known handle.  Complain if !force and closing a known handle or
215    if the name of the handle being closed does not match the registered name. */
216 bool __stdcall
217 close_handle (const char *func, int ln, HANDLE h, const char *name, bool force)
218 {
219   bool ret;
220
221   lock_debug here;
222   if (!mark_closed (func, ln, h, name, force))
223     return false;
224
225   SetHandleInformation (h, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
226   ret = CloseHandle (h);
227
228   if (!ret)
229     {
230       system_printf ("CloseHandle(%s<%p>) failed %s:%d, %E", name, h, func, ln);
231       try_to_debug ();
232     }
233   return ret;
234 }
235 #endif /*DEBUGGING*/