open-src/xserver/xorg/sun-src/os/solaris/mdb/modules/Xserver_clients.c
changeset 1265 0b5cc5c013e4
parent 1192 60e4ec16e28d
equal deleted inserted replaced
1264:a3323e4f263f 1265:0b5cc5c013e4
     1 /*
     1 /*
     2  * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
     3  *
     3  *
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     4  * Permission is hereby granted, free of charge, to any person obtaining a
     5  * copy of this software and associated documentation files (the "Software"),
     5  * copy of this software and associated documentation files (the "Software"),
     6  * to deal in the Software without restriction, including without limitation
     6  * to deal in the Software without restriction, including without limitation
     7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    21  * DEALINGS IN THE SOFTWARE.
    21  * DEALINGS IN THE SOFTWARE.
    22  */
    22  */
    23 
    23 
    24 
    24 
    25 #include <sys/mdb_modapi.h>
    25 #include <sys/mdb_modapi.h>
       
    26 #include <sys/procfs.h>
    26 #include "Xserver_mdb.h"
    27 #include "Xserver_mdb.h"
    27 
    28 
    28 #include "xorg-server.h"
    29 #include "xorg-server.h"
    29 #include "dixstruct.h"
    30 #include "dixstruct.h"
    30 #include "misc.h"
    31 #include "misc.h"
       
    32 #include "client.h"
    31 #include "os/osdep.h"
    33 #include "os/osdep.h"
    32 #include "IA/interactive_srv.h"
    34 #include "IA/interactive_srv.h"
    33 
    35 
    34 struct client_walk_data {
    36 struct client_walk_data {
    35     uintptr_t client_next;
    37     uintptr_t client_next;
   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     }