jvmti_rs/wrapper/jvmtifns/
stack_frame.rs1use std::ptr;
2
3use crate::{builder::*, errors::*, JVMTIEnv, objects::*};
4use crate::sys;
5use crate::sys::{jint, jvmtiFrameInfo, jvmtiStackInfo};
6
7impl<'a> JVMTIEnv<'a> {
8 pub fn get_stack_trace(&self, thread: &JThreadID, start_depth: jint, max_frame_count: jint) -> Result<(JFrameInfo, jint)> {
9 let mut frame_info: jvmtiFrameInfo = jvmtiFrameInfo {
10 method: ptr::null_mut(),
11 location: 0 as sys::jlocation,
12 };
13 let mut count: jint = 0 as jint;
14 let res = jvmti_call_result!(self.jvmti_raw(), GetStackTrace,
15 thread.into(),
16 start_depth,
17 max_frame_count,
18 &mut frame_info,
19 &mut count
20 );
21 jvmti_error_code_to_result(res)?;
22 Ok((frame_info.into(), count))
23 }
24
25 pub fn get_all_stack_traces(&self, max_frame_count: jint) -> Result<(Vec<JStackInfo>, jint)> {
26 let mut builder: MutAutoDeallocateObjectArrayBuilder<jvmtiStackInfo> = MutAutoDeallocateObjectArrayBuilder::with_size(max_frame_count);
27 let mut thread_count: jint = 0 as jint;
28 let res = jvmti_call_result!(self.jvmti_raw(), GetAllStackTraces,
29 max_frame_count,
30 &mut builder.items,
31 &mut thread_count
32 );
33 jvmti_error_code_to_result(res)?;
34 Ok((builder.build(self), thread_count))
35 }
36
37 pub fn get_thread_list_stack_traces(&self, threads: &Vec<JThreadID>, max_frame_count: jint) -> Result<Vec<JStackInfo>> {
38 if threads.is_empty() {
39 return Ok(vec![]);
40 }
41 let mut builder: MutAutoDeallocateObjectArrayBuilder<jvmtiStackInfo> = MutAutoDeallocateObjectArrayBuilder::with_size(max_frame_count);
42 let jthreads: Vec<sys::jthread> = threads.iter().map(|&e| e.into()).collect();
43 let res = jvmti_call_result!( self.jvmti_raw(), GetThreadListStackTraces,
44 jthreads.len() as jint,
45 jthreads.as_ptr(),
46 max_frame_count,
47 &mut builder.items
48 );
49 jvmti_error_code_to_result(res)?;
50 Ok(builder.build(self))
51 }
52
53 pub fn get_frame_count(&self, thread: &JThreadID) -> Result<jint> {
54 Ok(jvmti_call_number_result!(self.jvmti_raw(), jint,
55 GetFrameCount,
56 thread.into()
57 ))
58 }
59
60 pub fn get_frame_location(&self, thread: &JThreadID, depth: jint) -> Result<Option<JFrameInfo>> {
61 let mut info: jvmtiFrameInfo = jvmtiFrameInfo {
62 method: ptr::null_mut(),
63 location: 0,
64 };
65
66 let res = jvmti_call_result!(self.jvmti_raw(), GetFrameLocation,
67 thread.into(),
68 depth,
69 &mut info.method,
70 &mut info.location
71 );
72
73 jvmti_error_code_to_result(res)?;
74
75 if info.method.is_null() || info.location == 0 {
76 return Ok(None);
77 }
78 Ok(Some(info.into()))
79 }
80
81 pub fn pop_frame(&self, thread: &JThreadID) -> Result<()> {
82 jvmti_call!(self.jvmti_raw(), PopFrame,
83 thread.into()
84 )
85 }
86
87 pub fn notify_frame_pop(&self, thread: &JThreadID, depth: jint) -> Result<()> {
88 jvmti_call!(self.jvmti_raw(), NotifyFramePop,
89 thread.into(),
90 depth
91 )
92 }
93}