4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <mdb/mdb_modapi.h>
35 #include <libuutil_impl.h>
39 uutil_status(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
41 pthread_t uu_panic_thread
= 0;
43 if ((flags
& DCMD_ADDRSPEC
) || argc
!= 0)
46 if (mdb_readvar(&uu_panic_thread
, "uu_panic_thread") == -1) {
47 mdb_warn("unable to read uu_panic_thread");
50 if (uu_panic_thread
!= 0) {
51 mdb_printf("thread %d uu_panicked\n", uu_panic_thread
);
59 uutil_listpool(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
63 if (!(flags
& DCMD_ADDRSPEC
)) {
64 if (mdb_walk_dcmd("uu_list_pool", "uu_list_pool", argc
,
66 mdb_warn("can't walk uu_list_pool");
75 if (DCMD_HDRSPEC(flags
))
76 mdb_printf("%-?s %-30s %?s %5s\n",
77 "ADDR", "NAME", "COMPARE", "FLAGS");
79 if (mdb_vread(&ulp
, sizeof (uu_list_pool_t
), addr
) == -1) {
80 mdb_warn("failed to read uu_list_pool\n");
84 mdb_printf("%0?p %-30s %08x %c\n", addr
, ulp
.ulp_name
, ulp
.ulp_cmp
,
85 ulp
.ulp_debug
? 'D' : ' ');
92 uutil_list(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
96 if (!(flags
& DCMD_ADDRSPEC
) || argc
!= 0)
99 if (mdb_vread(&ul
, sizeof (uu_list_t
), addr
) == -1) {
100 mdb_warn("failed to read uu_list\n");
104 if (DCMD_HDRSPEC(flags
))
105 mdb_printf("%-?s %-?s %-?s %6s %5s\n",
106 "ADDR", "POOL", "PARENT", "NODES", "FLAGS");
108 mdb_printf("%0?p %0?p %0?p %6u %c%c\n",
109 addr
, ul
.ul_pool
, UU_PTR_DECODE(ul
.ul_parent_enc
),
110 ul
.ul_numnodes
, ul
.ul_sorted
? 'S' : ' ', ul
.ul_debug
? 'D' : ' ');
115 typedef struct uutil_listpool_walk
{
116 uintptr_t ulpw_final
;
117 uintptr_t ulpw_current
;
118 } uutil_listpool_walk_t
;
121 uutil_listpool_walk_init(mdb_walk_state_t
*wsp
)
123 uu_list_pool_t null_lpool
;
124 uutil_listpool_walk_t
*ulpw
;
127 bzero(&null_lpool
, sizeof (uu_list_pool_t
));
129 if (mdb_lookup_by_obj("libuutil.so.1", "uu_null_lpool", &sym
) ==
131 mdb_warn("failed to find 'uu_null_lpool'\n");
135 if (mdb_vread(&null_lpool
, sym
.st_size
, (uintptr_t)sym
.st_value
) ==
137 mdb_warn("failed to read data from 'uu_null_lpool' address\n");
141 ulpw
= mdb_alloc(sizeof (uutil_listpool_walk_t
), UM_SLEEP
);
143 ulpw
->ulpw_final
= (uintptr_t)null_lpool
.ulp_prev
;
144 ulpw
->ulpw_current
= (uintptr_t)null_lpool
.ulp_next
;
145 wsp
->walk_data
= ulpw
;
151 uutil_listpool_walk_step(mdb_walk_state_t
*wsp
)
154 uutil_listpool_walk_t
*ulpw
= wsp
->walk_data
;
157 if (mdb_vread(&ulp
, sizeof (uu_list_pool_t
),
158 ulpw
->ulpw_current
) == -1) {
159 mdb_warn("failed to read uu_list_pool %x", ulpw
->ulpw_current
);
163 status
= wsp
->walk_callback(ulpw
->ulpw_current
, &ulp
, wsp
->walk_cbdata
);
165 if (ulpw
->ulpw_current
== ulpw
->ulpw_final
)
168 ulpw
->ulpw_current
= (uintptr_t)ulp
.ulp_next
;
174 uutil_listpool_walk_fini(mdb_walk_state_t
*wsp
)
176 uutil_listpool_walk_t
*ulpw
= wsp
->walk_data
;
177 mdb_free(ulpw
, sizeof (uutil_listpool_walk_t
));
180 typedef struct uutil_list_walk
{
182 uintptr_t ulw_current
;
186 uutil_list_walk_init(mdb_walk_state_t
*wsp
)
188 uutil_list_walk_t
*ulw
;
191 if (mdb_vread(&ulp
, sizeof (uu_list_pool_t
), wsp
->walk_addr
) == -1) {
192 mdb_warn("failed to read uu_list_pool_t at given address\n");
196 if (UU_LIST_PTR(ulp
.ulp_null_list
.ul_next_enc
) ==
197 &((uu_list_pool_t
*)wsp
->walk_addr
)->ulp_null_list
)
200 ulw
= mdb_alloc(sizeof (uutil_list_walk_t
), UM_SLEEP
);
202 ulw
->ulw_final
= (uintptr_t)UU_LIST_PTR(ulp
.ulp_null_list
.ul_prev_enc
);
204 (uintptr_t)UU_LIST_PTR(ulp
.ulp_null_list
.ul_next_enc
);
205 wsp
->walk_data
= ulw
;
211 uutil_list_walk_step(mdb_walk_state_t
*wsp
)
214 uutil_list_walk_t
*ulw
= wsp
->walk_data
;
217 if (mdb_vread(&ul
, sizeof (uu_list_t
), ulw
->ulw_current
) == -1) {
218 mdb_warn("failed to read uu_list %x", ulw
->ulw_current
);
222 status
= wsp
->walk_callback(ulw
->ulw_current
, &ul
, wsp
->walk_cbdata
);
224 if (ulw
->ulw_current
== ulw
->ulw_final
)
227 ulw
->ulw_current
= (uintptr_t)UU_LIST_PTR(ul
.ul_next_enc
);
233 uutil_list_walk_fini(mdb_walk_state_t
*wsp
)
235 uutil_list_walk_t
*ulw
= wsp
->walk_data
;
236 mdb_free(ulw
, sizeof (uutil_list_walk_t
));
239 typedef struct uutil_list_node_walk
{
241 uintptr_t ulnw_final
;
242 uintptr_t ulnw_current
;
245 } uutil_list_node_walk_t
;
248 uutil_list_node_walk_init(mdb_walk_state_t
*wsp
)
250 uutil_list_node_walk_t
*ulnw
;
254 if (mdb_vread(&ul
, sizeof (uu_list_t
), wsp
->walk_addr
) == -1) {
255 mdb_warn("failed to read uu_list_t at given address\n");
259 if (mdb_vread(&ulp
, sizeof (uu_list_pool_t
), (uintptr_t)ul
.ul_pool
) ==
261 mdb_warn("failed to read supporting uu_list_pool_t\n");
265 ulnw
= mdb_alloc(sizeof (uutil_list_node_walk_t
), UM_SLEEP
);
267 ulnw
->ulnw_offset
= ul
.ul_offset
;
268 ulnw
->ulnw_final
= wsp
->walk_addr
+ offsetof(uu_list_t
, ul_null_node
);
269 ulnw
->ulnw_current
= (uintptr_t)ul
.ul_null_node
.uln_next
;
270 ulnw
->ulnw_buf
= mdb_alloc(ulp
.ulp_objsize
, UM_SLEEP
);
271 ulnw
->ulnw_bufsz
= ulp
.ulp_objsize
;
273 wsp
->walk_data
= ulnw
;
279 uutil_list_node_walk_step(mdb_walk_state_t
*wsp
)
281 uu_list_node_impl_t uln
;
282 uutil_list_node_walk_t
*ulnw
= wsp
->walk_data
;
286 if (ulnw
->ulnw_current
== ulnw
->ulnw_final
)
289 if (mdb_vread(&uln
, sizeof (uu_list_node_impl_t
), ulnw
->ulnw_current
) ==
291 mdb_warn("failed to read uu_list_node %x", ulnw
->ulnw_current
);
295 diff
= ulnw
->ulnw_current
- ulnw
->ulnw_offset
;
297 if (mdb_vread(ulnw
->ulnw_buf
, ulnw
->ulnw_bufsz
, diff
) == -1) {
298 mdb_warn("failed to read enclosing structure %x", diff
);
302 * Correct for offset; we return the address of the included structure.
304 status
= wsp
->walk_callback(diff
, ulnw
->ulnw_buf
, wsp
->walk_cbdata
);
306 ulnw
->ulnw_current
= (uintptr_t)uln
.uln_next
;
312 uutil_list_node_walk_fini(mdb_walk_state_t
*wsp
)
314 uutil_list_node_walk_t
*ulnw
= wsp
->walk_data
;
316 mdb_free(ulnw
->ulnw_buf
, ulnw
->ulnw_bufsz
);
317 mdb_free(ulnw
, sizeof (uutil_list_node_walk_t
));
320 static const mdb_dcmd_t dcmds
[] = {
321 { "uutil_status", NULL
, "libuutil status summary", uutil_status
},
322 { "uu_list_pool", NULL
, "display uu_list_pool information",
324 { "uu_list", NULL
, "display uu_list information",
329 static const mdb_walker_t walkers
[] = {
330 { "uu_list_pool", "walk uu_list_pools",
331 uutil_listpool_walk_init
, uutil_listpool_walk_step
,
332 uutil_listpool_walk_fini
},
333 { "uu_list", "given a uu_list_pool, walk its uu_lists",
334 uutil_list_walk_init
, uutil_list_walk_step
,
335 uutil_list_walk_fini
},
337 "given a uu_list, walk its nodes, returning container addr",
338 uutil_list_node_walk_init
, uutil_list_node_walk_step
,
339 uutil_list_node_walk_fini
},
343 static const mdb_modinfo_t modinfo
= {
344 MDB_API_VERSION
, dcmds
, walkers
347 const mdb_modinfo_t
*