jvmti_rs/wrapper/jvmtifns/
stack_frame.rs

1use 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}