141 client_walk_fini(mdb_walk_state_t *wsp) |
143 client_walk_fini(mdb_walk_state_t *wsp) |
142 { |
144 { |
143 mdb_free(wsp->walk_data, sizeof (ClientRec)); |
145 mdb_free(wsp->walk_data, sizeof (ClientRec)); |
144 } |
146 } |
145 |
147 |
|
148 _X_HIDDEN void |
|
149 client_pids_help(void) |
|
150 { |
|
151 mdb_printf( |
|
152 "Prints information about a ClientRec entry in the X server's array\n" |
|
153 "of currently connected X clients. Prints process pid and name that\n" |
|
154 "was recorded at connection time for each client, if available.\n" |
|
155 "\n" |
|
156 "If no %<u>addr%</u> is specified, uses ::client_walk to walk the linked list\n" |
|
157 "of ClientRec entries stored in the global array \"clients\" and print\n" |
|
158 "information about each one.\n" |
|
159 "\n"); |
|
160 (void) mdb_dec_indent(2); |
|
161 mdb_printf("%<b>OPTIONS%</b>\n"); |
|
162 (void) mdb_inc_indent(2); |
|
163 mdb_printf( |
|
164 "-w\tPrint arguments with process name when available.\n"); |
|
165 } |
|
166 |
146 _X_HIDDEN int |
167 _X_HIDDEN int |
147 client_pids(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) |
168 client_pids(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) |
148 { |
169 { |
149 uintptr_t clientP; |
170 uintptr_t clientP; |
150 ClientRec client_data; |
171 ClientRec client_data; |
151 |
172 uint_t show_cmd_args = FALSE; |
152 if (argc != 0) |
173 |
|
174 if (mdb_getopts(argc, argv, |
|
175 'w', MDB_OPT_SETBITS, TRUE, &show_cmd_args, |
|
176 NULL) != argc) |
153 return (DCMD_USAGE); |
177 return (DCMD_USAGE); |
154 |
178 |
155 /* |
179 /* |
156 * If no client address was specified on the command line, we can |
180 * If no client address was specified on the command line, we can |
157 * print out all clients by invoking the walker, using this |
181 * print out all clients by invoking the walker, using this |
169 /* |
193 /* |
170 * If this is the first invocation of the command, print a nice |
194 * If this is the first invocation of the command, print a nice |
171 * header line for the output that will follow. |
195 * header line for the output that will follow. |
172 */ |
196 */ |
173 if (DCMD_HDRSPEC(flags)) |
197 if (DCMD_HDRSPEC(flags)) |
174 mdb_printf("CLIENT SEQUENCE # FD PIDS\n"); |
198 mdb_printf("CLIENT SEQUENCE # FD PROCESS\n"); |
175 |
199 |
176 |
200 |
177 if (mdb_vread(&clientP, sizeof (clientP), addr) != sizeof (clientP)) { |
201 if (mdb_vread(&clientP, sizeof (clientP), addr) != sizeof (clientP)) { |
178 mdb_warn("failed to read ClientPtr at %p", addr); |
202 mdb_warn("failed to read ClientPtr at %p", addr); |
179 } else { |
203 } else { |
180 if (mdb_vread(&client_data, sizeof (client_data), clientP) |
204 if (mdb_vread(&client_data, sizeof (client_data), clientP) |
181 != sizeof (client_data)) { |
205 != sizeof (client_data)) { |
182 mdb_warn("failed to read ClientRec at %p", clientP); |
206 mdb_warn("failed to read ClientRec at %p", clientP); |
183 } else { |
207 } else { |
184 mdb_printf("%5d %10d", client_data.index, client_data.sequence); |
208 int client_pid = -1; |
185 |
209 |
186 if (client_data.osPrivate == NULL) { |
210 mdb_printf("%5d %10d ", client_data.index, client_data.sequence); |
187 mdb_printf(" ??? - NULL ClientPtr->osPrivate\n"); |
211 |
188 } else { |
212 /* Find file descriptor for this client */ |
|
213 if (client_data.osPrivate != NULL) { |
189 OsCommRec oscomm; |
214 OsCommRec oscomm; |
190 |
215 |
191 if (mdb_vread(&oscomm, sizeof (oscomm), |
216 if (mdb_vread(&oscomm, sizeof (oscomm), |
192 (uintptr_t)client_data.osPrivate) |
217 (uintptr_t)client_data.osPrivate) |
193 != sizeof (oscomm)) { |
218 != sizeof (oscomm)) { |
194 mdb_warn("failed to read struct OsCommRec at %p", |
219 mdb_warn("failed to read struct OsCommRec at %p", |
195 client_data.osPrivate); |
220 client_data.osPrivate); |
196 } else { |
221 } else { |
197 ClientProcessPtr cpp = NULL; |
|
198 |
|
199 /* Xorg 1.9 or later */ |
|
200 DevPrivateKeyRec IAPrivKeyRec; |
|
201 GElf_Sym privkey_sym; |
|
202 |
|
203 mdb_printf("%4d ", oscomm.fd); |
222 mdb_printf("%4d ", oscomm.fd); |
204 |
223 } |
205 if (mdb_lookup_by_obj("libia.so", "IAPrivKeyRec", |
224 } else { |
206 &privkey_sym) == -1) { |
225 mdb_printf("NULL "); |
207 mdb_warn("failed to lookup 'libia.so`IAPrivKeyRec'"); |
226 } |
|
227 |
|
228 /* Find client pid & cmd recorded on connection setup by |
|
229 Xorg 1.11 and later */ |
|
230 if (client_data.clientIds != NULL) { |
|
231 ClientIdRec cir; |
|
232 |
|
233 if (mdb_vread(&cir, sizeof (cir), |
|
234 (uintptr_t)client_data.clientIds) |
|
235 != sizeof (cir)) { |
|
236 mdb_warn("failed to read struct ClientIdRec at %p", |
|
237 client_data.clientIds); |
|
238 } else { |
|
239 char cmd[PRARGSZ]; |
|
240 |
|
241 if (mdb_readstr(cmd, sizeof(cmd), |
|
242 (uintptr_t)cir.cmdname) == -1) { |
|
243 mdb_warn("failed to read cmdname at %p", cir.cmdname); |
|
244 cmd[0] = '\0'; |
|
245 } |
|
246 mdb_printf("%6d %s", cir.pid, cmd); |
|
247 client_pid = cir.pid; |
|
248 if (show_cmd_args && (cir.cmdargs != NULL)) { |
|
249 if (mdb_readstr(cmd, sizeof(cmd), |
|
250 (uintptr_t)cir.cmdargs) == -1) { |
|
251 mdb_warn("failed to read cmdargs at %p", |
|
252 cir.cmdargs); |
|
253 cmd[0] = '\0'; |
|
254 } |
|
255 mdb_printf(" %s\n", cmd); |
208 } else { |
256 } else { |
209 if (mdb_vread(&IAPrivKeyRec, sizeof(DevPrivateKeyRec), |
257 mdb_printf("\n", cmd); |
210 privkey_sym.st_value) |
258 } |
211 != sizeof(DevPrivateKeyRec)) { |
259 } |
212 mdb_warn("failed to read 'IAPrivKeyRec'"); |
260 } else { |
213 } else if (!IAPrivKeyRec.initialized) { |
261 mdb_printf(" ???? - NULL ClientPtr->clientIds\n"); |
214 mdb_warn("IAPrivKeyRec is uninitialized"); |
262 } |
215 } else { |
263 |
216 uintptr_t dpaddr |
264 /* Check to see if any additional pids were registered |
217 = ((uintptr_t)client_data.devPrivates) |
265 with SolarisIA extension. */ |
218 + IAPrivKeyRec.offset; |
266 static GElf_Sym iaprivkey_sym; |
219 uintptr_t cppaddr = (uintptr_t) NULL; |
267 |
220 |
268 if ((iaprivkey_sym.st_value == 0) && |
221 /* |
269 (mdb_lookup_by_obj("libia.so", "IAPrivKeyRec", &iaprivkey_sym) |
222 * ClientProcessPtr is the first entry in the |
270 == -1)) { |
223 * IAClientPrivatePtr that devPrivates points to |
271 mdb_warn("failed to lookup 'libia.so`IAPrivKeyRec'"); |
224 */ |
272 } |
225 if (mdb_vread(&cppaddr, sizeof (cppaddr), dpaddr) |
273 |
226 != sizeof (cppaddr)) { |
274 if (iaprivkey_sym.st_value != 0) { |
227 mdb_warn("failed to read " |
275 ClientProcessPtr cpp = NULL; |
228 " client_data.devPrivates+offset"); |
276 DevPrivateKeyRec IAPrivKeyRec; |
229 } else if (cppaddr == NULL) { |
277 |
230 mdb_warn("no ClientProcessPtr found"); |
278 if (mdb_vread(&IAPrivKeyRec, sizeof(DevPrivateKeyRec), |
231 } else if (mdb_vread(&cpp, sizeof (cpp), cppaddr) |
279 iaprivkey_sym.st_value) |
232 != sizeof (cpp)) { |
280 != sizeof(DevPrivateKeyRec)) { |
233 cpp = NULL; |
281 mdb_warn("failed to read 'IAPrivKeyRec'"); |
234 mdb_warn("failed to read IAClientPrivatePtr"); |
282 } else if (!IAPrivKeyRec.initialized) { |
|
283 mdb_warn("IAPrivKeyRec is uninitialized"); |
|
284 } else { |
|
285 uintptr_t dpaddr = ((uintptr_t)client_data.devPrivates) |
|
286 + IAPrivKeyRec.offset; |
|
287 uintptr_t cppaddr = (uintptr_t) NULL; |
|
288 |
|
289 /* |
|
290 * ClientProcessPtr is the first entry in the |
|
291 * IAClientPrivatePtr that devPrivates points to |
|
292 */ |
|
293 if (mdb_vread(&cppaddr, sizeof (cppaddr), dpaddr) |
|
294 != sizeof (cppaddr)) { |
|
295 mdb_warn("failed to read " |
|
296 " client_data.devPrivates+offset"); |
|
297 } else if (cppaddr == NULL) { |
|
298 /* |
|
299 * if osPrivate is NULL, client connection is closed, |
|
300 * and it's no surprise we can't find ClientProcessPtr |
|
301 */ |
|
302 if (client_data.osPrivate != NULL) |
|
303 mdb_warn("no ClientProcessPtr found"); |
|
304 } else if (mdb_vread(&cpp, sizeof (cpp), cppaddr) |
|
305 != sizeof (cpp)) { |
|
306 cpp = NULL; |
|
307 mdb_warn("failed to read IAClientPrivatePtr"); |
|
308 } |
|
309 } |
|
310 |
|
311 if (cpp != NULL) { |
|
312 ClientProcessRec cpr; |
|
313 ConnectionPidRec pid; |
|
314 |
|
315 if (mdb_vread(&cpr, sizeof (cpr), (uintptr_t)cpp) |
|
316 != sizeof (cpr)) { |
|
317 mdb_warn("failed to read struct ClientProcessRec" |
|
318 " at %p", client_data.osPrivate); |
|
319 } else { |
|
320 int i, num_printed = 0; |
|
321 uintptr_t pidP = (uintptr_t) cpr.pids; |
|
322 |
|
323 for (i = 0; i < cpr.count; i++, pidP += sizeof(pid)) { |
|
324 if (mdb_vread(&pid, sizeof (pid), pidP) |
|
325 == sizeof (pid)) { |
|
326 if (pid != client_pid) { |
|
327 if (num_printed == 0) |
|
328 mdb_printf("%22s", "+"); |
|
329 num_printed++; |
|
330 mdb_printf(" %6d", pid); |
|
331 } |
|
332 } else { |
|
333 mdb_warn("failed to read pid #%d from %p", |
|
334 i, pidP); |
235 } |
335 } |
236 } |
336 } |
237 } |
337 if (num_printed != 0) |
238 |
|
239 if (cpp == NULL) { |
|
240 mdb_printf(" ??? - NULL ClientProcessPtr\n"); |
|
241 } else { |
|
242 ClientProcessRec cpr; |
|
243 ConnectionPidRec pid; |
|
244 |
|
245 if (mdb_vread(&cpr, sizeof (cpr), (uintptr_t)cpp) |
|
246 != sizeof (cpr)) { |
|
247 mdb_warn("failed to read struct ClientProcessRec" |
|
248 " at %p", client_data.osPrivate); |
|
249 } else { |
|
250 int i; |
|
251 uintptr_t pidP = (uintptr_t) cpr.pids; |
|
252 |
|
253 for (i = 0; i < cpr.count; |
|
254 i++, pidP += sizeof(pid)) { |
|
255 if (mdb_vread(&pid, sizeof (pid), pidP) |
|
256 == sizeof (pid)) { |
|
257 mdb_printf("%d ", pid); |
|
258 } else { |
|
259 mdb_warn("failed to read pid #%d from %p", |
|
260 i, pidP); |
|
261 } |
|
262 } |
|
263 mdb_printf("\n"); |
338 mdb_printf("\n"); |
264 } |
|
265 } |
339 } |
266 } |
340 } |
267 } |
341 } |
268 } |
342 } |
269 } |
343 } |