JavaScript is required to for searching.
Skip Navigation Links
Exit Print View
Solaris Dynamic Tracing Guide
search filter icon
search icon

Document Information

Preface

1.  Introduction

2.  Types, Operators, and Expressions

3.  Variables

4.  D Program Structure

5.  Pointers and Arrays

6.  Strings

7.  Structs and Unions

8.  Type and Constant Definitions

9.  Aggregations

10.  Actions and Subroutines

11.  Buffers and Buffering

12.  Output Formatting

13.  Speculative Tracing

14.  dtrace(1M) Utility

15.  Scripting

16.  Options and Tunables

17.  dtrace Provider

18.  lockstat Provider

19.  profile Provider

20.  fbt Provider

21.  syscall Provider

22.  sdt Provider

23.  sysinfo Provider

24.  vminfo Provider

25.  proc Provider

26.  sched Provider

27.  io Provider

28.  mib Provider

29.  fpuinfo Provider

30.  pid Provider

31.  plockstat Provider

32.  fasttrap Provider

33.  User Process Tracing

copyin() and copyinstr() Subroutines

Avoiding Errors

Eliminating dtrace(1M) Interference

syscall Provider

ustack() Action

uregs[] Array

pid Provider

User Function Boundary Tracing

Tracing Arbitrary Instructions

34.  Statically Defined Tracing for User Applications

35.  Security

36.  Anonymous Tracing

37.  Postmortem Tracing

38.  Performance Considerations

39.  Stability

40.  Translators

41.  Versioning

Glossary

Index

ustack() Action

Tracing a process thread's stack at the time a particular probe is activated is often useful for examining a problem in more detail. The ustack() action traces the user thread's stack. If, for example, a process that opens many files occasionally fails in the open(2) system call, you can use the ustack() action to discover the code path that executes the failed open():

syscall::open:entry
/pid == $1/
{
    self->path = copyinstr(arg0);
}

syscall::open:return
/self->path != NULL && arg1 == -1/
{
    printf("open for '%s' failed", self->path);
    ustack();
}

This script also illustrates the use of the $1 macro variable which takes the value of the first operand specified on the dtrace(1M) command-line:

# dtrace -s ./badopen.d 31337
dtrace: script './badopen.d' matched 2 probes
CPU     ID                    FUNCTION:NAME
  0     40                      open:return open for '/usr/lib/foo' failed
              libc.so.1`__open+0x4
              libc.so.1`open+0x6c
              420b0
              tcsh`dosource+0xe0
              tcsh`execute+0x978
              tcsh`execute+0xba0
              tcsh`process+0x50c
              tcsh`main+0x1d54
              tcsh`_start+0xdc

The ustack() action records program counter (PC) values for the stack and dtrace(1M) resolves those PC values to symbol names by looking though the process's symbol tables. If dtrace can't resolve the PC value to a symbol, it will print out the value as a hexadecimal integer.

If a process exits or is killed before the ustack() data is formatted for output, dtrace might be unable to convert the PC values in the stack trace to symbol names, and will be forced to display them as hexadecimal integers. To work around this limitation, specify a process of interest with the -c or -p option to dtrace. See Chapter 14, dtrace(1M) Utility for details on these and other options. If the process ID or command is not known in advance, the following example D program that can be used to work around the limitation:

/*
 * This example uses the open(2) system call probe, but this technique
 * is applicable to any script using the ustack() action where the stack
 * being traced is in a process that may exit soon.
 */
 syscall::open:entry
{
    ustack();
    stop_pids[pid] = 1;
}

syscall::rexit:entry
/stop_pids[pid] != 0/
{
    printf("stopping pid %d", pid);
    stop();
    stop_pids[pid] = 0;
}

The above script stops a process just before it exits if the ustack() action has been applied to a thread in that process. This technique ensures that the dtrace command will be able to resolve the PC values to symbolic names. Notice that the value of stop_pids[pid] is set to 0 after it has been used to clear the dynamic variable. Remember to set stopped processes running again using the prun(1) command or your system will accumulate many stopped processes.