Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,9 @@ $ plgrp -a 0-2 101398
synopsis: "[-q] [pid[/tid] | core]...",
options: &[(
"-q, --quiet",
"Suppress demangling, module path, source location, and inline frame \
information. Only addresses and raw symbol names with offsets are shown.",
"Suppress demangling, module path, source location, inline frame, \
and argument information. Only addresses and raw symbol names with \
offsets are shown.",
)],
operands: &[
(
Expand Down
49 changes: 30 additions & 19 deletions src/bin/pstack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
use std::path::Path;
use std::process::exit;

use ptools::stack::SourceLocation;
use ptools::stack::{FrameArgs, SourceLocation};
use ptools::ProcHandle;

fn format_source(src: &SourceLocation) -> String {
Expand Down Expand Up @@ -45,7 +45,8 @@ fn print_stack(
.demangle(!quiet)
.module(!quiet)
.source(!quiet)
.inlines(!quiet);
.inlines(!quiet)
.args(!quiet);
let process = if let Some(path) = core_path {
opts.trace_core(path, handle)?
} else {
Expand All @@ -66,26 +67,36 @@ fn print_stack(
}
println!("{}: {}", thread.id(), thread.name().unwrap_or("<unknown>"));
for frame in thread.frames() {
if frame.is_inline() {
match frame.symbol() {
Some(symbol) => {
print!("{:#016x} {} [inlined]", frame.ip(), symbol.name());
print!("{:#018x}", frame.ip());

if let Some(symbol) = frame.symbol() {
print!(" in {}", symbol.name());

// Print arguments inside parentheses
match frame.args() {
Some(FrameArgs::Args(args)) => {
print!("(");
for (i, arg) in args.iter().enumerate() {
if i > 0 {
print!(", ");
}
print!("{}={}", arg.name(), arg.value());
}
print!(")");
}
None => print!("{:#016x} - ??? [inlined]", frame.ip()),
Some(FrameArgs::NoDebugInfo) => print!("()"),
None => {}
}
} else {
match frame.symbol() {
Some(symbol) => {
print!(
"{:#016x} {}+{:#x}",
frame.ip(),
symbol.name(),
symbol.offset()
);
}
None => print!("{:#016x} - ???", frame.ip()),

if frame.is_inline() {
print!(" [inlined]");
} else {
print!("+{:#x}", symbol.offset());
}
} else {
print!(" - ???");
}

if let Some(module) = frame.module() {
print!(" in {module}");
}
Expand All @@ -110,7 +121,7 @@ fn print_usage() {
eprintln!("Print stack traces of running processes or core dumps.");
eprintln!();
eprintln!("Options:");
eprintln!(" -q, --quiet Suppress demangling, module, and source info");
eprintln!(" -q, --quiet Suppress demangling, module, source, and argument info");
eprintln!(" -h, --help Print help");
eprintln!(" -V, --version Print version");
}
Expand Down
12 changes: 12 additions & 0 deletions src/dw/dwfl/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,16 @@ impl FrameRef {
}
}
}

/// Returns the value of a register at this frame.
pub fn reg(&self, regno: u32) -> Option<u64> {
unsafe {
let mut val: crate::dw_sys::Dwarf_Word = 0;
if crate::dw_sys::dwfl_frame_reg(self.as_ptr(), regno, &mut val) == 0 {
Some(val)
} else {
None
}
}
}
}
35 changes: 35 additions & 0 deletions src/dw_sys/dwarf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,38 @@ pub const DW_AT_GNU_all_source_call_sites: c_uint = 0x2118;
pub const DW_AT_GNU_macros: c_uint = 0x2119;
pub const DW_AT_GNU_deleted: c_uint = 0x211a;
pub const DW_AT_hi_user: c_uint = 0x3fff;

// DWARF expression operations
pub const DW_OP_addr: u8 = 0x03;
pub const DW_OP_deref: u8 = 0x06;
pub const DW_OP_const1u: u8 = 0x08;
pub const DW_OP_const1s: u8 = 0x09;
pub const DW_OP_const2u: u8 = 0x0a;
pub const DW_OP_const2s: u8 = 0x0b;
pub const DW_OP_const4u: u8 = 0x0c;
pub const DW_OP_const4s: u8 = 0x0d;
pub const DW_OP_const8u: u8 = 0x0e;
pub const DW_OP_const8s: u8 = 0x0f;
pub const DW_OP_constu: u8 = 0x10;
pub const DW_OP_consts: u8 = 0x11;
pub const DW_OP_plus_uconst: u8 = 0x23;
pub const DW_OP_reg0: u8 = 0x50;
pub const DW_OP_reg31: u8 = 0x6f;
pub const DW_OP_breg0: u8 = 0x70;
pub const DW_OP_breg31: u8 = 0x8f;
pub const DW_OP_regx: u8 = 0x90;
pub const DW_OP_fbreg: u8 = 0x91;
pub const DW_OP_bregx: u8 = 0x92;
pub const DW_OP_piece: u8 = 0x93;
pub const DW_OP_call_frame_cfa: u8 = 0x9c;
pub const DW_OP_stack_value: u8 = 0x9f;

// DWARF base type encodings
pub const DW_ATE_address: c_uint = 0x01;
pub const DW_ATE_boolean: c_uint = 0x02;
pub const DW_ATE_float: c_uint = 0x04;
pub const DW_ATE_signed: c_uint = 0x05;
pub const DW_ATE_signed_char: c_uint = 0x06;
pub const DW_ATE_unsigned: c_uint = 0x07;
pub const DW_ATE_unsigned_char: c_uint = 0x08;
pub const DW_ATE_UTF: c_uint = 0x10;
Loading
Loading