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 /*
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <mdb/mdb_modapi.h>
27 #include <mdb/mdb_ctf.h>
28
29 #include <sys/types.h>
30 #include <sys/regset.h>
31 #include <sys/stack.h>
32 #include <sys/thread.h>
33 #include <sys/modctl.h>
34 #include <assert.h>
35
36 #include "findstack.h"
37 #include "thread.h"
38 #include "sobj.h"
39
40 int findstack_debug_on = 0;
41
42 /*
43 * "sp" is a kernel VA.
323 * This way, we can get at all of the data, even if qsort() was
324 * interrupted while mucking with the array.
325 */
326 if (stacks_hash != NULL) {
327 for (idx = 0; idx < STACKS_HSIZE; idx++) {
328 while ((cur = stacks_hash[idx]) != NULL) {
329 while ((next = cur->se_dup) != NULL) {
330 cur->se_dup = next->se_dup;
331 mdb_free(next,
332 STACKS_ENTRY_SIZE(next->se_depth));
333 }
334 next = cur->se_next;
335 stacks_hash[idx] = next;
336 mdb_free(cur, STACKS_ENTRY_SIZE(cur->se_depth));
337 }
338 }
339 if (stacks_array != NULL)
340 mdb_free(stacks_array,
341 stacks_array_size * sizeof (*stacks_array));
342
343 } else if (stacks_array != NULL) {
344 for (idx = 0; idx < stacks_array_size; idx++) {
345 if ((cur = stacks_array[idx]) != NULL) {
346 while ((next = cur->se_dup) != NULL) {
347 cur->se_dup = next->se_dup;
348 mdb_free(next,
349 STACKS_ENTRY_SIZE(next->se_depth));
350 }
351 stacks_array[idx] = NULL;
352 mdb_free(cur, STACKS_ENTRY_SIZE(cur->se_depth));
353 }
354 }
355 mdb_free(stacks_array,
356 stacks_array_size * sizeof (*stacks_array));
357 }
358
359 stacks_findstack_cleanup();
360
361 stacks_array_size = 0;
362 stacks_state = STACKS_STATE_CLEAN;
363 }
364
365 /*ARGSUSED*/
366 int
367 stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg)
368 {
369 stacks_info_t *sip = cbarg;
370 findstack_info_t *fsip = &sip->si_fsi;
371
372 stacks_entry_t **sepp, *nsep, *sep;
373 int idx;
374 size_t depth;
375
376 if (stacks_findstack(addr, fsip, 0) != DCMD_OK &&
377 fsip->fsi_failed == FSI_FAIL_BADTHREAD) {
378 mdb_warn("couldn't read thread at %p\n", addr);
379 return (WALK_NEXT);
380 }
381
382 sip->si_count++;
|
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 /*
23 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
25 */
26
27 #include <mdb/mdb_modapi.h>
28 #include <mdb/mdb_ctf.h>
29
30 #include <sys/types.h>
31 #include <sys/regset.h>
32 #include <sys/stack.h>
33 #include <sys/thread.h>
34 #include <sys/modctl.h>
35 #include <assert.h>
36
37 #include "findstack.h"
38 #include "thread.h"
39 #include "sobj.h"
40
41 int findstack_debug_on = 0;
42
43 /*
44 * "sp" is a kernel VA.
324 * This way, we can get at all of the data, even if qsort() was
325 * interrupted while mucking with the array.
326 */
327 if (stacks_hash != NULL) {
328 for (idx = 0; idx < STACKS_HSIZE; idx++) {
329 while ((cur = stacks_hash[idx]) != NULL) {
330 while ((next = cur->se_dup) != NULL) {
331 cur->se_dup = next->se_dup;
332 mdb_free(next,
333 STACKS_ENTRY_SIZE(next->se_depth));
334 }
335 next = cur->se_next;
336 stacks_hash[idx] = next;
337 mdb_free(cur, STACKS_ENTRY_SIZE(cur->se_depth));
338 }
339 }
340 if (stacks_array != NULL)
341 mdb_free(stacks_array,
342 stacks_array_size * sizeof (*stacks_array));
343
344 mdb_free(stacks_hash, STACKS_HSIZE * sizeof (*stacks_hash));
345
346 } else if (stacks_array != NULL) {
347 for (idx = 0; idx < stacks_array_size; idx++) {
348 if ((cur = stacks_array[idx]) != NULL) {
349 while ((next = cur->se_dup) != NULL) {
350 cur->se_dup = next->se_dup;
351 mdb_free(next,
352 STACKS_ENTRY_SIZE(next->se_depth));
353 }
354 stacks_array[idx] = NULL;
355 mdb_free(cur, STACKS_ENTRY_SIZE(cur->se_depth));
356 }
357 }
358 mdb_free(stacks_array,
359 stacks_array_size * sizeof (*stacks_array));
360 }
361
362 stacks_findstack_cleanup();
363
364 stacks_array_size = 0;
365 stacks_state = STACKS_STATE_CLEAN;
366 stacks_hash = NULL;
367 stacks_array = NULL;
368 }
369
370 /*ARGSUSED*/
371 int
372 stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg)
373 {
374 stacks_info_t *sip = cbarg;
375 findstack_info_t *fsip = &sip->si_fsi;
376
377 stacks_entry_t **sepp, *nsep, *sep;
378 int idx;
379 size_t depth;
380
381 if (stacks_findstack(addr, fsip, 0) != DCMD_OK &&
382 fsip->fsi_failed == FSI_FAIL_BADTHREAD) {
383 mdb_warn("couldn't read thread at %p\n", addr);
384 return (WALK_NEXT);
385 }
386
387 sip->si_count++;
|