2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
31 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
32 * Import of Mac OS X kernel (~semeria)
34 * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
35 * Import of OSF Mach kernel (~mburg)
37 * Revision 1.1.16.3 1996/01/09 19:16:26 devrcs
38 * Make db_lookup_task_id() globally available (remove static).
39 * Changed declarations of 'register foo' to 'register int foo'.
40 * [1995/12/01 21:42:37 jfraser]
42 * Merged '64-bit safe' changes from DEC alpha port.
43 * [1995/11/21 18:03:48 jfraser]
45 * Revision 1.1.16.2 1994/09/23 01:21:59 ezf
46 * change marker to not FREE
47 * [1994/09/22 21:11:09 ezf]
49 * Revision 1.1.16.1 1994/06/11 21:12:29 bolinger
50 * Merge up to NMK17.2.
51 * [1994/06/11 20:02:43 bolinger]
53 * Revision 1.1.14.1 1994/02/08 10:59:02 bernadat
54 * Added support of DB_VAR_SHOW.
58 * Revision 1.1.12.3 1994/03/17 22:35:35 dwm
59 * The infamous name change: thread_activation + thread_shuttle = thread.
60 * [1994/03/17 21:25:50 dwm]
62 * Revision 1.1.12.2 1994/01/17 18:08:54 dwm
63 * Add patchable integer force_act_lookup to force successful
64 * lookup, to allow stack trace on orphaned act/thread pairs.
65 * [1994/01/17 16:06:50 dwm]
67 * Revision 1.1.12.1 1994/01/12 17:50:52 dwm
68 * Coloc: initial restructuring to follow Utah model.
69 * [1994/01/12 17:13:23 dwm]
71 * Revision 1.1.3.3 1993/07/27 18:28:15 elliston
72 * Add ANSI prototypes. CR #9523.
73 * [1993/07/27 18:13:06 elliston]
75 * Revision 1.1.3.2 1993/06/02 23:12:39 jeffc
76 * Added to OSF/1 R1.3 from NMK15.0.
77 * [1993/06/02 20:57:24 jeffc]
79 * Revision 1.1 1992/09/30 02:01:27 robert
86 * Revision 2.2 91/10/09 16:03:04 af
87 * Revision 2.1.3.1 91/10/05 13:07:50 jeffreyh
88 * Created for task/thread handling.
91 * Revision 2.1.3.1 91/10/05 13:07:50 jeffreyh
92 * Created for task/thread handling.
98 * Mach Operating System
99 * Copyright (c) 1991,1990 Carnegie Mellon University
100 * All Rights Reserved.
102 * Permission to use, copy, modify and distribute this software and its
103 * documentation is hereby granted, provided that both the copyright
104 * notice and this permission notice appear in all copies of the
105 * software, derivative works or modified versions, and any portions
106 * thereof, and that both notices appear in supporting documentation.
108 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
109 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
110 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
112 * Carnegie Mellon requests users of this software to return to
114 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
115 * School of Computer Science
116 * Carnegie Mellon University
117 * Pittsburgh PA 15213-3890
119 * any improvements or extensions that they make and grant Carnegie Mellon
120 * the rights to redistribute these changes.
125 #include <kern/kern_types.h>
126 #include <kern/processor.h>
127 #include <machine/db_machdep.h>
128 #include <ddb/db_task_thread.h>
129 #include <ddb/db_variables.h>
130 #include <ddb/db_command.h>
131 #include <ddb/db_expr.h>
132 #include <ddb/db_lex.h>
133 #include <ddb/db_output.h> /* For db_printf() */
134 #include <ddb/db_sym.h>
137 * Following constants are used to prevent infinite loop of task
138 * or thread search due to the incorrect list.
140 #define DB_MAX_TASKID 0x10000 /* max # of tasks */
141 #define DB_MAX_THREADID 0x10000 /* max # of threads in a task */
142 #define DB_MAX_PSETS 0x10000 /* max # of processor sets */
144 task_t db_default_task
; /* default target task */
145 thread_act_t db_default_act
; /* default target thr_act */
149 /* Prototypes for functions local to this file.
151 task_t
db_lookup_task_id(register int task_id
);
153 static thread_act_t
db_lookup_act_id(
155 register int thread_id
);
160 * search valid task queue, and return the queue position as the task id
163 db_lookup_task(task_t target_task
)
165 register task_t task
;
166 register int task_id
;
167 register processor_set_t pset
= &default_pset
;
168 register int npset
= 0;
171 if (npset
++ >= DB_MAX_PSETS
)
173 if (queue_first(&pset
->tasks
) == 0)
175 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
176 if (target_task
== task
)
178 if (task_id
++ >= DB_MAX_TASKID
)
185 * search thread queue of the task, and return the queue position
190 thread_act_t target_act
)
192 register thread_act_t thr_act
;
196 if (queue_first(&task
->thr_acts
) == 0)
198 queue_iterate(&task
->thr_acts
, thr_act
, thread_act_t
, thr_acts
) {
199 if (target_act
== thr_act
)
201 if (act_id
++ >= DB_MAX_THREADID
)
208 * search thr_act queue of every valid task, and return the queue position
212 db_lookup_act(thread_act_t target_act
)
215 register task_t task
;
216 register processor_set_t pset
= &default_pset
;
217 register int ntask
= 0;
218 register int npset
= 0;
220 if (npset
++ >= DB_MAX_PSETS
)
222 if (queue_first(&pset
->tasks
) == 0)
224 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
225 if (ntask
++ > DB_MAX_TASKID
)
227 if (task
->thr_act_count
== 0)
229 act_id
= db_lookup_task_act(task
, target_act
);
237 * check the address is a valid thread address
239 int force_act_lookup
= 0;
241 db_check_act_address_valid(thread_act_t thr_act
)
243 if (!force_act_lookup
&& db_lookup_act(thr_act
) < 0) {
244 db_printf("Bad thr_act address 0x%x\n", thr_act
);
252 * convert task_id(queue postion) to task address
255 db_lookup_task_id(register task_id
)
257 register task_t task
;
258 register processor_set_t pset
= &default_pset
;
259 register int npset
= 0;
261 if (task_id
> DB_MAX_TASKID
)
263 if (npset
++ >= DB_MAX_PSETS
)
265 if (queue_first(&pset
->tasks
) == 0)
267 queue_iterate(&pset
->tasks
, task
, task_t
, pset_tasks
) {
275 * convert (task_id, act_id) pair to thr_act address
282 register thread_act_t thr_act
;
285 if (act_id
> DB_MAX_THREADID
)
286 return(THR_ACT_NULL
);
287 if (queue_first(&task
->thr_acts
) == 0)
288 return(THR_ACT_NULL
);
289 queue_iterate(&task
->thr_acts
, thr_act
, thread_act_t
, thr_acts
) {
293 return(THR_ACT_NULL
);
297 * get next parameter from a command line, and check it as a valid
306 thread_act_t thr_act
;
308 *actp
= THR_ACT_NULL
;
309 if (db_expression(&value
)) {
310 thr_act
= (thread_act_t
) value
;
311 if (!db_check_act_address_valid(thr_act
)) {
315 } else if (position
<= 0) {
316 thr_act
= db_default_act
;
324 * check the default thread is still valid
325 * ( it is called in entering DDB session )
328 db_init_default_act(void)
330 if (db_lookup_act(db_default_act
) < 0) {
331 db_default_act
= THR_ACT_NULL
;
332 db_default_task
= TASK_NULL
;
334 db_default_task
= db_default_act
->task
;
338 * set or get default thread which is used when /t or :t option is specified
339 * in the command line
343 struct db_variable
*vp
,
346 db_var_aux_param_t ap
) /* unused */
348 thread_act_t thr_act
;
352 if (flag
== DB_VAR_SHOW
) {
353 db_printf("%#n", db_default_act
);
354 task_id
= db_lookup_task(db_default_task
);
356 act_id
= db_lookup_act(db_default_act
);
358 db_printf(" (task%d.%d)", task_id
, act_id
);
364 if (flag
!= DB_VAR_SET
) {
365 *valuep
= (db_expr_t
) db_default_act
;
368 thr_act
= (thread_act_t
) *valuep
;
369 if (thr_act
!= THR_ACT_NULL
&& !db_check_act_address_valid(thr_act
))
372 db_default_act
= thr_act
;
374 db_default_task
= thr_act
->task
;
379 * convert $taskXXX[.YYY] type DDB variable to task or thread address
383 struct db_variable
*vp
,
386 db_var_aux_param_t ap
)
389 thread_act_t thr_act
;
392 if (flag
== DB_VAR_SHOW
) {
393 db_printf("%#n", db_default_task
);
394 task_id
= db_lookup_task(db_default_task
);
396 db_printf(" (task%d)", task_id
);
400 if (flag
!= DB_VAR_GET
) {
401 db_error("Cannot set to $task variable\n");
404 if ((task
= db_lookup_task_id(ap
->suffix
[0])) == TASK_NULL
) {
405 db_printf("no such task($task%d)\n", ap
->suffix
[0]);
409 if (ap
->level
<= 1) {
410 *valuep
= (db_expr_t
) task
;
413 if ((thr_act
= db_lookup_act_id(task
, ap
->suffix
[1])) == THR_ACT_NULL
){
414 db_printf("no such thr_act($task%d.%d)\n",
415 ap
->suffix
[0], ap
->suffix
[1]);
419 *valuep
= (db_expr_t
) thr_act
;