Print this page
4229 mdb hangs on exit when long umem cache names exist
Reviewed by: Robert Mustacchi <rm@joyent.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2013 by Delphix. All rights reserved.
  23  * Copyright (c) 2012 Joyent, Inc. All rights reserved.

  24  */
  25 /*
  26  * This file contains all of the interfaces for mdb's tab completion engine.
  27  * Currently some interfaces are private to mdb and its internal implementation,
  28  * those are in mdb_tab.h. Other pieces are public interfaces. Those are in
  29  * mdb_modapi.h.
  30  *
  31  * Memory allocations in tab completion context have to be done very carefully.
  32  * We need to think of ourselves as the same as any other command that is being
  33  * executed by the user, which means we must use UM_GC to handle being
  34  * interrupted.
  35  */
  36 
  37 #include <mdb/mdb_modapi.h>
  38 #include <mdb/mdb_ctf.h>
  39 #include <mdb/mdb_ctf_impl.h>
  40 #include <mdb/mdb_string.h>
  41 #include <mdb/mdb_module.h>
  42 #include <mdb/mdb_debug.h>
  43 #include <mdb/mdb_print.h>


 377         mcp = mdb_zalloc(sizeof (mdb_tab_cookie_t), UM_SLEEP | UM_GC);
 378         (void) mdb_nv_create(&mcp->mtc_nv, UM_SLEEP | UM_GC);
 379 
 380         return (mcp);
 381 }
 382 
 383 size_t
 384 mdb_tab_size(mdb_tab_cookie_t *mcp)
 385 {
 386         return (mdb_nv_size(&mcp->mtc_nv));
 387 }
 388 
 389 /*
 390  * Determine whether the specified name is a valid tab completion for
 391  * the given command. If the name is a valid tab completion then
 392  * it will be saved in the mdb_tab_cookie_t.
 393  */
 394 void
 395 mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name)
 396 {
 397         size_t len, matches, index;
 398         uint_t flags;
 399         mdb_var_t *v;
 400         char *n;
 401         const char *nvn;
 402 
 403         /*
 404          * If we have a match set, then we want to verify that we actually match
 405          * it.
 406          */
 407         if (mcp->mtc_base != NULL &&
 408             strncmp(name, mcp->mtc_base, strlen(mcp->mtc_base)) != 0)
 409                 return;
 410 
 411         v = mdb_nv_lookup(&mcp->mtc_nv, name);
 412         if (v != NULL)
 413                 return;
 414 
 415         /*
 416          * Names that we get passed in may be longer than MDB_NV_NAMELEN which
 417          * is currently 31 including the null terminator. If that is the case,
 418          * then we're going to take care of allocating a string and holding it
 419          * for our caller. Note that we don't need to free it, because we're
 420          * allocating this with UM_GC.
 421          */
 422         flags = 0;
 423         len = strlen(name);
 424         if (len > MDB_NV_NAMELEN - 1) {
 425                 n = mdb_alloc(len + 1, UM_SLEEP | UM_GC);
 426                 (void) strcpy(n, name);
 427                 nvn = n;
 428                 flags |= MDB_NV_EXTNAME;
 429         } else {
 430                 nvn = name;
 431         }
 432         flags |= MDB_NV_RDONLY;
 433 
 434         (void) mdb_nv_insert(&mcp->mtc_nv, nvn, NULL, 0, flags);
 435 
 436         matches = mdb_tab_size(mcp);
 437         if (matches == 1) {
 438                 (void) strlcpy(mcp->mtc_match, nvn, MDB_SYM_NAMLEN);
 439         } else {
 440                 index = 0;
 441                 while (mcp->mtc_match[index] &&
 442                     mcp->mtc_match[index] == nvn[index])
 443                         index++;
 444 
 445                 mcp->mtc_match[index] = '\0';
 446         }
 447 }
 448 
 449 /*ARGSUSED*/
 450 static int
 451 tab_print_cb(mdb_var_t *v, void *ignored)
 452 {
 453         mdb_printf("%s\n", mdb_nv_get_name(v));
 454         return (0);
 455 }
 456 
 457 void
 458 mdb_tab_print(mdb_tab_cookie_t *mcp)
 459 {
 460         mdb_nv_sort_iter(&mcp->mtc_nv, tab_print_cb, NULL, UM_SLEEP | UM_GC);
 461 }
 462 




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2013 by Delphix. All rights reserved.
  23  * Copyright (c) 2012 Joyent, Inc. All rights reserved.
  24  * Copyright (c) 2013 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  25  */
  26 /*
  27  * This file contains all of the interfaces for mdb's tab completion engine.
  28  * Currently some interfaces are private to mdb and its internal implementation,
  29  * those are in mdb_tab.h. Other pieces are public interfaces. Those are in
  30  * mdb_modapi.h.
  31  *
  32  * Memory allocations in tab completion context have to be done very carefully.
  33  * We need to think of ourselves as the same as any other command that is being
  34  * executed by the user, which means we must use UM_GC to handle being
  35  * interrupted.
  36  */
  37 
  38 #include <mdb/mdb_modapi.h>
  39 #include <mdb/mdb_ctf.h>
  40 #include <mdb/mdb_ctf_impl.h>
  41 #include <mdb/mdb_string.h>
  42 #include <mdb/mdb_module.h>
  43 #include <mdb/mdb_debug.h>
  44 #include <mdb/mdb_print.h>


 378         mcp = mdb_zalloc(sizeof (mdb_tab_cookie_t), UM_SLEEP | UM_GC);
 379         (void) mdb_nv_create(&mcp->mtc_nv, UM_SLEEP | UM_GC);
 380 
 381         return (mcp);
 382 }
 383 
 384 size_t
 385 mdb_tab_size(mdb_tab_cookie_t *mcp)
 386 {
 387         return (mdb_nv_size(&mcp->mtc_nv));
 388 }
 389 
 390 /*
 391  * Determine whether the specified name is a valid tab completion for
 392  * the given command. If the name is a valid tab completion then
 393  * it will be saved in the mdb_tab_cookie_t.
 394  */
 395 void
 396 mdb_tab_insert(mdb_tab_cookie_t *mcp, const char *name)
 397 {
 398         size_t matches, index;

 399         mdb_var_t *v;


 400 
 401         /*
 402          * If we have a match set, then we want to verify that we actually match
 403          * it.
 404          */
 405         if (mcp->mtc_base != NULL &&
 406             strncmp(name, mcp->mtc_base, strlen(mcp->mtc_base)) != 0)
 407                 return;
 408 
 409         v = mdb_nv_lookup(&mcp->mtc_nv, name);
 410         if (v != NULL)
 411                 return;
 412 
 413         (void) mdb_nv_insert(&mcp->mtc_nv, name, NULL, 0, MDB_NV_RDONLY);



















 414 
 415         matches = mdb_tab_size(mcp);
 416         if (matches == 1) {
 417                 (void) strlcpy(mcp->mtc_match, name, MDB_SYM_NAMLEN);
 418         } else {
 419                 index = 0;
 420                 while (mcp->mtc_match[index] &&
 421                     mcp->mtc_match[index] == name[index])
 422                         index++;
 423 
 424                 mcp->mtc_match[index] = '\0';
 425         }
 426 }
 427 
 428 /*ARGSUSED*/
 429 static int
 430 tab_print_cb(mdb_var_t *v, void *ignored)
 431 {
 432         mdb_printf("%s\n", mdb_nv_get_name(v));
 433         return (0);
 434 }
 435 
 436 void
 437 mdb_tab_print(mdb_tab_cookie_t *mcp)
 438 {
 439         mdb_nv_sort_iter(&mcp->mtc_nv, tab_print_cb, NULL, UM_SLEEP | UM_GC);
 440 }
 441