The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/ddb/db_command.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  *
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  *
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  *
   16  * Carnegie Mellon requests users of this software to return to
   17  *
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  *
   23  * any improvements or extensions that they make and grant Carnegie the
   24  * rights to redistribute these changes.
   25  */
   26 /*
   27  *      Author: David B. Golub, Carnegie Mellon University
   28  *      Date:   7/90
   29  */
   30 /*
   31  * Command dispatcher.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD: src/sys/ddb/db_command.c,v 1.57.2.2 2005/01/30 00:59:21 imp Exp $");
   36 
   37 #include <sys/param.h>
   38 #include <sys/linker_set.h>
   39 #include <sys/lock.h>
   40 #include <sys/kdb.h>
   41 #include <sys/mutex.h>
   42 #include <sys/proc.h>
   43 #include <sys/reboot.h>
   44 #include <sys/signalvar.h>
   45 #include <sys/systm.h>
   46 #include <sys/cons.h>
   47 #include <sys/watchdog.h>
   48 
   49 #include <ddb/ddb.h>
   50 #include <ddb/db_command.h>
   51 #include <ddb/db_lex.h>
   52 #include <ddb/db_output.h>
   53 
   54 #include <machine/cpu.h>
   55 #include <machine/setjmp.h>
   56 
   57 /*
   58  * Exported global variables
   59  */
   60 boolean_t       db_cmd_loop_done;
   61 db_addr_t       db_dot;
   62 db_addr_t       db_last_addr;
   63 db_addr_t       db_prev;
   64 db_addr_t       db_next;
   65 
   66 SET_DECLARE(db_cmd_set, struct command);
   67 SET_DECLARE(db_show_cmd_set, struct command);
   68 
   69 static db_cmdfcn_t      db_fncall;
   70 static db_cmdfcn_t      db_gdb;
   71 static db_cmdfcn_t      db_kill;
   72 static db_cmdfcn_t      db_reset;
   73 static db_cmdfcn_t      db_stack_trace;
   74 static db_cmdfcn_t      db_watchdog;
   75 
   76 /* XXX this is actually forward-static. */
   77 extern struct command   db_show_cmds[];
   78 
   79 /*
   80  * if 'ed' style: 'dot' is set at start of last item printed,
   81  * and '+' points to next line.
   82  * Otherwise: 'dot' points to next item, '..' points to last.
   83  */
   84 static boolean_t        db_ed_style = TRUE;
   85 
   86 /*
   87  * Utility routine - discard tokens through end-of-line.
   88  */
   89 void
   90 db_skip_to_eol()
   91 {
   92         int     t;
   93         do {
   94             t = db_read_token();
   95         } while (t != tEOL);
   96 }
   97 
   98 /*
   99  * Results of command search.
  100  */
  101 #define CMD_UNIQUE      0
  102 #define CMD_FOUND       1
  103 #define CMD_NONE        2
  104 #define CMD_AMBIGUOUS   3
  105 #define CMD_HELP        4
  106 
  107 static void     db_cmd_list(struct command *table, struct command **aux_tablep,
  108                     struct command **aux_tablep_end);
  109 static int      db_cmd_search(char *name, struct command *table,
  110                     struct command **aux_tablep,
  111                     struct command **aux_tablep_end, struct command **cmdp);
  112 static void     db_command(struct command **last_cmdp,
  113                     struct command *cmd_table, struct command **aux_cmd_tablep,
  114                     struct command **aux_cmd_tablep_end);
  115 
  116 /*
  117  * Search for command prefix.
  118  */
  119 static int
  120 db_cmd_search(name, table, aux_tablep, aux_tablep_end, cmdp)
  121         char *          name;
  122         struct command  *table;
  123         struct command  **aux_tablep;
  124         struct command  **aux_tablep_end;
  125         struct command  **cmdp; /* out */
  126 {
  127         struct command  *cmd;
  128         struct command  **aux_cmdp;
  129         int             result = CMD_NONE;
  130 
  131         for (cmd = table; cmd->name != 0; cmd++) {
  132             register char *lp;
  133             register char *rp;
  134             register int  c;
  135 
  136             lp = name;
  137             rp = cmd->name;
  138             while ((c = *lp) == *rp) {
  139                 if (c == 0) {
  140                     /* complete match */
  141                     *cmdp = cmd;
  142                     return (CMD_UNIQUE);
  143                 }
  144                 lp++;
  145                 rp++;
  146             }
  147             if (c == 0) {
  148                 /* end of name, not end of command -
  149                    partial match */
  150                 if (result == CMD_FOUND) {
  151                     result = CMD_AMBIGUOUS;
  152                     /* but keep looking for a full match -
  153                        this lets us match single letters */
  154                 }
  155                 else {
  156                     *cmdp = cmd;
  157                     result = CMD_FOUND;
  158                 }
  159             }
  160         }
  161         if (result == CMD_NONE && aux_tablep != 0)
  162             /* XXX repeat too much code. */
  163             for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) {
  164                 register char *lp;
  165                 register char *rp;
  166                 register int  c;
  167 
  168                 lp = name;
  169                 rp = (*aux_cmdp)->name;
  170                 while ((c = *lp) == *rp) {
  171                     if (c == 0) {
  172                         /* complete match */
  173                         *cmdp = *aux_cmdp;
  174                         return (CMD_UNIQUE);
  175                     }
  176                     lp++;
  177                     rp++;
  178                 }
  179                 if (c == 0) {
  180                     /* end of name, not end of command -
  181                        partial match */
  182                     if (result == CMD_FOUND) {
  183                         result = CMD_AMBIGUOUS;
  184                         /* but keep looking for a full match -
  185                            this lets us match single letters */
  186                     }
  187                     else {
  188                         *cmdp = *aux_cmdp;
  189                         result = CMD_FOUND;
  190                     }
  191                 }
  192             }
  193         if (result == CMD_NONE) {
  194             /* check for 'help' */
  195                 if (name[0] == 'h' && name[1] == 'e'
  196                     && name[2] == 'l' && name[3] == 'p')
  197                         result = CMD_HELP;
  198         }
  199         return (result);
  200 }
  201 
  202 static void
  203 db_cmd_list(table, aux_tablep, aux_tablep_end)
  204         struct command *table;
  205         struct command **aux_tablep;
  206         struct command **aux_tablep_end;
  207 {
  208         register struct command *cmd;
  209         register struct command **aux_cmdp;
  210 
  211         for (cmd = table; cmd->name != 0; cmd++) {
  212             db_printf("%-12s", cmd->name);
  213             db_end_line();
  214         }
  215         if (aux_tablep == 0)
  216             return;
  217         for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) {
  218             db_printf("%-12s", (*aux_cmdp)->name);
  219             db_end_line();
  220         }
  221 }
  222 
  223 static void
  224 db_command(last_cmdp, cmd_table, aux_cmd_tablep, aux_cmd_tablep_end)
  225         struct command  **last_cmdp;    /* IN_OUT */
  226         struct command  *cmd_table;
  227         struct command  **aux_cmd_tablep;
  228         struct command  **aux_cmd_tablep_end;
  229 {
  230         struct command  *cmd;
  231         int             t;
  232         char            modif[TOK_STRING_SIZE];
  233         db_expr_t       addr, count;
  234         boolean_t       have_addr = FALSE;
  235         int             result;
  236 
  237         t = db_read_token();
  238         if (t == tEOL) {
  239             /* empty line repeats last command, at 'next' */
  240             cmd = *last_cmdp;
  241             addr = (db_expr_t)db_next;
  242             have_addr = FALSE;
  243             count = 1;
  244             modif[0] = '\0';
  245         }
  246         else if (t == tEXCL) {
  247             db_fncall((db_expr_t)0, (boolean_t)0, (db_expr_t)0, (char *)0);
  248             return;
  249         }
  250         else if (t != tIDENT) {
  251             db_printf("?\n");
  252             db_flush_lex();
  253             return;
  254         }
  255         else {
  256             /*
  257              * Search for command
  258              */
  259             while (cmd_table) {
  260                 result = db_cmd_search(db_tok_string,
  261                                        cmd_table,
  262                                        aux_cmd_tablep,
  263                                        aux_cmd_tablep_end,
  264                                        &cmd);
  265                 switch (result) {
  266                     case CMD_NONE:
  267                         db_printf("No such command\n");
  268                         db_flush_lex();
  269                         return;
  270                     case CMD_AMBIGUOUS:
  271                         db_printf("Ambiguous\n");
  272                         db_flush_lex();
  273                         return;
  274                     case CMD_HELP:
  275                         db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end);
  276                         db_flush_lex();
  277                         return;
  278                     default:
  279                         break;
  280                 }
  281                 if ((cmd_table = cmd->more) != 0) {
  282                     /* XXX usually no more aux's. */
  283                     aux_cmd_tablep = 0;
  284                     if (cmd_table == db_show_cmds) {
  285                         aux_cmd_tablep = SET_BEGIN(db_show_cmd_set);
  286                         aux_cmd_tablep_end = SET_LIMIT(db_show_cmd_set);
  287                     }
  288 
  289                     t = db_read_token();
  290                     if (t != tIDENT) {
  291                         db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end);
  292                         db_flush_lex();
  293                         return;
  294                     }
  295                 }
  296             }
  297 
  298             if ((cmd->flag & CS_OWN) == 0) {
  299                 /*
  300                  * Standard syntax:
  301                  * command [/modifier] [addr] [,count]
  302                  */
  303                 t = db_read_token();
  304                 if (t == tSLASH) {
  305                     t = db_read_token();
  306                     if (t != tIDENT) {
  307                         db_printf("Bad modifier\n");
  308                         db_flush_lex();
  309                         return;
  310                     }
  311                     db_strcpy(modif, db_tok_string);
  312                 }
  313                 else {
  314                     db_unread_token(t);
  315                     modif[0] = '\0';
  316                 }
  317 
  318                 if (db_expression(&addr)) {
  319                     db_dot = (db_addr_t) addr;
  320                     db_last_addr = db_dot;
  321                     have_addr = TRUE;
  322                 }
  323                 else {
  324                     addr = (db_expr_t) db_dot;
  325                     have_addr = FALSE;
  326                 }
  327                 t = db_read_token();
  328                 if (t == tCOMMA) {
  329                     if (!db_expression(&count)) {
  330                         db_printf("Count missing\n");
  331                         db_flush_lex();
  332                         return;
  333                     }
  334                 }
  335                 else {
  336                     db_unread_token(t);
  337                     count = -1;
  338                 }
  339                 if ((cmd->flag & CS_MORE) == 0) {
  340                     db_skip_to_eol();
  341                 }
  342             }
  343         }
  344         *last_cmdp = cmd;
  345         if (cmd != 0) {
  346             /*
  347              * Execute the command.
  348              */
  349             (*cmd->fcn)(addr, have_addr, count, modif);
  350             db_setup_paging(NULL, NULL, -1);
  351 
  352             if (cmd->flag & CS_SET_DOT) {
  353                 /*
  354                  * If command changes dot, set dot to
  355                  * previous address displayed (if 'ed' style).
  356                  */
  357                 if (db_ed_style) {
  358                     db_dot = db_prev;
  359                 }
  360                 else {
  361                     db_dot = db_next;
  362                 }
  363             }
  364             else {
  365                 /*
  366                  * If command does not change dot,
  367                  * set 'next' location to be the same.
  368                  */
  369                 db_next = db_dot;
  370             }
  371         }
  372 }
  373 
  374 /*
  375  * 'show' commands
  376  */
  377 
  378 static struct command db_show_all_cmds[] = {
  379         { "procs",      db_ps,                  0,      0 },
  380         { (char *)0 }
  381 };
  382 
  383 static struct command db_show_cmds[] = {
  384         { "all",        0,                      0,      db_show_all_cmds },
  385         { "registers",  db_show_regs,           0,      0 },
  386         { "breaks",     db_listbreak_cmd,       0,      0 },
  387         { "threads",    db_show_threads,        0,      0 },
  388         { (char *)0, }
  389 };
  390 
  391 static struct command db_command_table[] = {
  392         { "print",      db_print_cmd,           0,      0 },
  393         { "p",          db_print_cmd,           0,      0 },
  394         { "examine",    db_examine_cmd,         CS_SET_DOT, 0 },
  395         { "x",          db_examine_cmd,         CS_SET_DOT, 0 },
  396         { "search",     db_search_cmd,          CS_OWN|CS_SET_DOT, 0 },
  397         { "set",        db_set_cmd,             CS_OWN, 0 },
  398         { "write",      db_write_cmd,           CS_MORE|CS_SET_DOT, 0 },
  399         { "w",          db_write_cmd,           CS_MORE|CS_SET_DOT, 0 },
  400         { "delete",     db_delete_cmd,          0,      0 },
  401         { "d",          db_delete_cmd,          0,      0 },
  402         { "break",      db_breakpoint_cmd,      0,      0 },
  403         { "dwatch",     db_deletewatch_cmd,     0,      0 },
  404         { "watch",      db_watchpoint_cmd,      CS_MORE,0 },
  405         { "dhwatch",    db_deletehwatch_cmd,    0,      0 },
  406         { "hwatch",     db_hwatchpoint_cmd,     0,      0 },
  407         { "step",       db_single_step_cmd,     0,      0 },
  408         { "s",          db_single_step_cmd,     0,      0 },
  409         { "continue",   db_continue_cmd,        0,      0 },
  410         { "c",          db_continue_cmd,        0,      0 },
  411         { "until",      db_trace_until_call_cmd,0,      0 },
  412         { "next",       db_trace_until_matching_cmd,0,  0 },
  413         { "match",      db_trace_until_matching_cmd,0,  0 },
  414         { "trace",      db_stack_trace,         CS_OWN, 0 },
  415         { "where",      db_stack_trace,         CS_OWN, 0 },
  416         { "call",       db_fncall,              CS_OWN, 0 },
  417         { "show",       0,                      0,      db_show_cmds },
  418         { "ps",         db_ps,                  0,      0 },
  419         { "gdb",        db_gdb,                 0,      0 },
  420         { "reset",      db_reset,               0,      0 },
  421         { "kill",       db_kill,                CS_OWN, 0 },
  422         { "watchdog",   db_watchdog,            0,      0 },
  423         { "thread",     db_set_thread,          CS_OWN, 0 },
  424         { (char *)0, }
  425 };
  426 
  427 static struct command   *db_last_command = 0;
  428 
  429 /*
  430  * At least one non-optional command must be implemented using
  431  * DB_COMMAND() so that db_cmd_set gets created.  Here is one.
  432  */
  433 DB_COMMAND(panic, db_panic)
  434 {
  435         panic("from debugger");
  436 }
  437 
  438 void
  439 db_command_loop()
  440 {
  441         /*
  442          * Initialize 'prev' and 'next' to dot.
  443          */
  444         db_prev = db_dot;
  445         db_next = db_dot;
  446 
  447         db_cmd_loop_done = 0;
  448         while (!db_cmd_loop_done) {
  449             if (db_print_position() != 0)
  450                 db_printf("\n");
  451 
  452             db_printf("db> ");
  453             (void) db_read_line();
  454 
  455             db_command(&db_last_command, db_command_table,
  456                        SET_BEGIN(db_cmd_set), SET_LIMIT(db_cmd_set));
  457         }
  458 }
  459 
  460 void
  461 db_error(s)
  462         const char *s;
  463 {
  464         if (s)
  465             db_printf("%s", s);
  466         db_flush_lex();
  467         kdb_reenter();
  468 }
  469 
  470 
  471 /*
  472  * Call random function:
  473  * !expr(arg,arg,arg)
  474  */
  475 static void
  476 db_fncall(dummy1, dummy2, dummy3, dummy4)
  477         db_expr_t       dummy1;
  478         boolean_t       dummy2;
  479         db_expr_t       dummy3;
  480         char *          dummy4;
  481 {
  482         db_expr_t       fn_addr;
  483 #define MAXARGS         11      /* XXX only 10 are passed */
  484         db_expr_t       args[MAXARGS];
  485         int             nargs = 0;
  486         db_expr_t       retval;
  487         typedef db_expr_t fcn_10args_t(db_expr_t, db_expr_t, db_expr_t,
  488                             db_expr_t, db_expr_t, db_expr_t, db_expr_t,
  489                             db_expr_t, db_expr_t, db_expr_t);
  490         fcn_10args_t    *func;
  491         int             t;
  492 
  493         if (!db_expression(&fn_addr)) {
  494             db_printf("Bad function\n");
  495             db_flush_lex();
  496             return;
  497         }
  498         func = (fcn_10args_t *)fn_addr; /* XXX */
  499 
  500         t = db_read_token();
  501         if (t == tLPAREN) {
  502             if (db_expression(&args[0])) {
  503                 nargs++;
  504                 while ((t = db_read_token()) == tCOMMA) {
  505                     if (nargs == MAXARGS) {
  506                         db_printf("Too many arguments\n");
  507                         db_flush_lex();
  508                         return;
  509                     }
  510                     if (!db_expression(&args[nargs])) {
  511                         db_printf("Argument missing\n");
  512                         db_flush_lex();
  513                         return;
  514                     }
  515                     nargs++;
  516                 }
  517                 db_unread_token(t);
  518             }
  519             if (db_read_token() != tRPAREN) {
  520                 db_printf("?\n");
  521                 db_flush_lex();
  522                 return;
  523             }
  524         }
  525         db_skip_to_eol();
  526 
  527         while (nargs < MAXARGS) {
  528             args[nargs++] = 0;
  529         }
  530 
  531         retval = (*func)(args[0], args[1], args[2], args[3], args[4],
  532                          args[5], args[6], args[7], args[8], args[9] );
  533         db_printf("%#lr\n", (long)retval);
  534 }
  535 
  536 static void
  537 db_kill(dummy1, dummy2, dummy3, dummy4)
  538         db_expr_t       dummy1;
  539         boolean_t       dummy2;
  540         db_expr_t       dummy3;
  541         char *          dummy4;
  542 {
  543         db_expr_t old_radix, pid, sig;
  544         struct proc *p;
  545 
  546 #define DB_ERROR(f)     do { db_printf f; db_flush_lex(); goto out; } while (0)
  547 
  548         /*
  549          * PIDs and signal numbers are typically represented in base
  550          * 10, so make that the default here.  It can, of course, be
  551          * overridden by specifying a prefix.
  552          */
  553         old_radix = db_radix;
  554         db_radix = 10;
  555         /* Retrieve arguments. */
  556         if (!db_expression(&sig))
  557                 DB_ERROR(("Missing signal number\n"));
  558         if (!db_expression(&pid))
  559                 DB_ERROR(("Missing process ID\n"));
  560         db_skip_to_eol();
  561         if (sig < 0 || sig > _SIG_MAXSIG)
  562                 DB_ERROR(("Signal number out of range\n"));
  563 
  564         /*
  565          * Find the process in question.  allproc_lock is not needed
  566          * since we're in DDB.
  567          */
  568         /* sx_slock(&allproc_lock); */
  569         LIST_FOREACH(p, &allproc, p_list)
  570             if (p->p_pid == pid)
  571                     break;
  572         /* sx_sunlock(&allproc_lock); */
  573         if (p == NULL)
  574                 DB_ERROR(("Can't find process with pid %ld\n", (long) pid));
  575 
  576         /* If it's already locked, bail; otherwise, do the deed. */
  577         if (PROC_TRYLOCK(p) == 0)
  578                 DB_ERROR(("Can't lock process with pid %ld\n", (long) pid));
  579         else {
  580                 psignal(p, sig);
  581                 PROC_UNLOCK(p);
  582         }
  583 
  584 out:
  585         db_radix = old_radix;
  586 #undef DB_ERROR
  587 }
  588 
  589 static void
  590 db_reset(dummy1, dummy2, dummy3, dummy4)
  591         db_expr_t       dummy1;
  592         boolean_t       dummy2;
  593         db_expr_t       dummy3;
  594         char *          dummy4;
  595 {
  596 
  597         cpu_reset();
  598 }
  599 
  600 static void
  601 db_watchdog(dummy1, dummy2, dummy3, dummy4)
  602         db_expr_t       dummy1;
  603         boolean_t       dummy2;
  604         db_expr_t       dummy3;
  605         char *          dummy4;
  606 {
  607         int i;
  608 
  609         /*
  610          * XXX: It might make sense to be able to set the watchdog to a
  611          * XXX: timeout here so that failure or hang as a result of subsequent
  612          * XXX: ddb commands could be recovered by a reset.
  613          */
  614 
  615         EVENTHANDLER_INVOKE(watchdog_list, 0, &i);
  616 }
  617 
  618 static void
  619 db_gdb(db_expr_t dummy1, boolean_t dummy2, db_expr_t dummy3, char *dummy4)
  620 {
  621 
  622         if (kdb_dbbe_select("gdb") != 0)
  623                 db_printf("The remote GDB backend could not be selected.\n");
  624         else
  625                 db_printf("Step to enter the remote GDB backend.\n");
  626 }
  627 
  628 static void
  629 db_stack_trace(db_expr_t tid, boolean_t hastid, db_expr_t count, char *modif)
  630 {
  631         struct thread *td;
  632         db_expr_t radix;
  633         pid_t pid;
  634         int t;
  635 
  636         /*
  637          * We parse our own arguments. We don't like the default radix.
  638          */
  639         radix = db_radix;
  640         db_radix = 10;
  641         hastid = db_expression(&tid);
  642         t = db_read_token();
  643         if (t == tCOMMA) {
  644                 if (!db_expression(&count)) {
  645                         db_printf("Count missing\n");
  646                         db_flush_lex();
  647                         return;
  648                 }
  649         } else {
  650                 db_unread_token(t);
  651                 count = -1;
  652         }
  653         db_skip_to_eol();
  654         db_radix = radix;
  655 
  656         if (hastid) {
  657                 td = kdb_thr_lookup((lwpid_t)tid);
  658                 if (td == NULL)
  659                         td = kdb_thr_from_pid((pid_t)tid);
  660                 if (td == NULL) {
  661                         db_printf("Thread %d not found\n", (int)tid);
  662                         return;
  663                 }
  664         } else
  665                 td = kdb_thread;
  666         if (td->td_proc != NULL)
  667                 pid = td->td_proc->p_pid;
  668         else
  669                 pid = -1;
  670         db_printf("Tracing pid %d tid %ld td %p\n", pid, (long)td->td_tid, td);
  671         db_trace_thread(td, count);
  672 }

Cache object: 064d96ee53e633bbd858a51384a4715c


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.