Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SBValue crash and add some features #24

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ mod instructionlist;
mod launchinfo;
mod lineentry;
mod listener;
mod memoryregioninfo;
mod memoryregioninfolist;
mod module;
mod modulespec;
mod platform;
Expand Down Expand Up @@ -191,6 +193,8 @@ pub use self::instructionlist::{SBInstructionList, SBInstructionListIter};
pub use self::launchinfo::SBLaunchInfo;
pub use self::lineentry::SBLineEntry;
pub use self::listener::SBListener;
pub use self::memoryregioninfo::SBMemoryRegionInfo;
pub use self::memoryregioninfolist::{SBMemoryRegionInfoList, SBMemoryRegionInfoListIter};
pub use self::module::{SBModule, SBModuleSectionIter};
pub use self::modulespec::SBModuleSpec;
pub use self::platform::SBPlatform;
Expand Down
98 changes: 98 additions & 0 deletions src/memoryregioninfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
use crate::sys;
use lldb_addr_t;
use std::ffi::CStr;

#[allow(missing_docs)]
#[derive(Debug)]
pub struct SBMemoryRegionInfo {
pub raw: sys::SBMemoryRegionInfoRef,
}

impl SBMemoryRegionInfo {
#[allow(missing_docs)]
pub fn new() -> Self {
SBMemoryRegionInfo::from(unsafe { sys::CreateSBMemoryRegionInfo() })
}

#[allow(missing_docs)]
pub fn clear(&self) {
unsafe { sys::SBMemoryRegionInfoClear(self.raw) };
}

/*
pub fn get_description(&self, description: SBStream) -> SBStream {
}
*/
Comment on lines +22 to +25
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about the implementation here. Do we create a new SBFrame and return it as an option if sys::SBMemoryRegionInfoGetDescription returns true ? in the source code of lldb, it always returns true. Or Do we take an SBFrame in parameter and pass it in the sys function ?


#[allow(missing_docs)]
pub fn is_executable(&self) -> bool {
unsafe { sys::SBMemoryRegionInfoIsExecutable(self.raw) }
}

#[allow(missing_docs)]
pub fn is_mapped(&self) -> bool {
unsafe { sys::SBMemoryRegionInfoIsMapped(self.raw) }
}

#[allow(missing_docs)]
pub fn is_readable(&self) -> bool {
unsafe { sys::SBMemoryRegionInfoIsReadable(self.raw) }
}

#[allow(missing_docs)]
pub fn is_writable(&self) -> bool {
unsafe { sys::SBMemoryRegionInfoIsWritable(self.raw) }
}

#[allow(missing_docs)]
pub fn get_name(&self) -> Option<String> {
unsafe {
let ptr = sys::SBMemoryRegionInfoGetName(self.raw);

if !ptr.is_null() {
match CStr::from_ptr(ptr).to_str() {
Ok(s) => Some(s.to_owned()),
_ => panic!("No MemoryRegionInfo name string?"),
}
} else {
None
}
}
}

#[allow(missing_docs)]
pub fn get_region_base(&self) -> lldb_addr_t {
unsafe { sys::SBMemoryRegionInfoGetRegionBase(self.raw) }
}

#[allow(missing_docs)]
pub fn get_region_end(&self) -> lldb_addr_t {
unsafe { sys::SBMemoryRegionInfoGetRegionEnd(self.raw) }
}
}

impl Clone for SBMemoryRegionInfo {
fn clone(&self) -> Self {
Self {
raw: unsafe { sys::CloneSBMemoryRegionInfo(self.raw) },
}
}
}

impl Default for SBMemoryRegionInfo {
fn default() -> Self {
Self::new()
}
}

impl Drop for SBMemoryRegionInfo {
fn drop(&mut self) {
unsafe { sys::DisposeSBMemoryRegionInfo(self.raw) };
}
}

impl From<sys::SBMemoryRegionInfoRef> for SBMemoryRegionInfo {
fn from(raw: sys::SBMemoryRegionInfoRef) -> Self {
Self { raw }
}
}
106 changes: 106 additions & 0 deletions src/memoryregioninfolist.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
use crate::sys;
use crate::SBMemoryRegionInfo;

#[allow(missing_docs)]
#[derive(Debug)]
pub struct SBMemoryRegionInfoList {
pub raw: sys::SBMemoryRegionInfoListRef,
}

impl SBMemoryRegionInfoList {
#[allow(missing_docs)]
pub fn new() -> Self {
SBMemoryRegionInfoList::from(unsafe { sys::CreateSBMemoryRegionInfoList() })
}

#[allow(missing_docs)]
pub fn append(&self, region: SBMemoryRegionInfo) {
unsafe { sys::SBMemoryRegionInfoListAppend(self.raw, region.raw) };
}

#[allow(missing_docs)]
pub fn append_list(&self, region_list: SBMemoryRegionInfoList) {
unsafe { sys::SBMemoryRegionInfoListAppendList(self.raw, region_list.raw) };
}

#[allow(missing_docs)]
pub fn clear(&self) {
unsafe { sys::SBMemoryRegionInfoListClear(self.raw) };
}

#[allow(missing_docs)]
pub fn get_memory_region(&self, index: u32) -> Option<SBMemoryRegionInfo> {
let tmp = SBMemoryRegionInfo::default();
if unsafe { sys::SBMemoryRegionInfoListGetMemoryRegionAtIndex(self.raw, index, tmp.raw) } {
Some(tmp)
} else {
None
}
}

#[allow(missing_docs)]
pub fn get_size(&self) -> u32 {
unsafe { sys::SBMemoryRegionInfoListGetSize(self.raw) }
}

#[allow(missing_docs)]
pub fn iter(&self) -> SBMemoryRegionInfoListIter {
SBMemoryRegionInfoListIter {
memory_list: self,
idx: 0,
}
}
}

impl Clone for SBMemoryRegionInfoList {
fn clone(&self) -> Self {
Self {
raw: unsafe { sys::CloneSBMemoryRegionInfoList(self.raw) },
}
}
}

impl Default for SBMemoryRegionInfoList {
fn default() -> Self {
Self::new()
}
}

impl Drop for SBMemoryRegionInfoList {
fn drop(&mut self) {
unsafe { sys::DisposeSBMemoryRegionInfoList(self.raw) };
}
}

impl From<sys::SBMemoryRegionInfoListRef> for SBMemoryRegionInfoList {
fn from(raw: sys::SBMemoryRegionInfoListRef) -> Self {
Self { raw }
}
}

#[allow(missing_docs)]
pub struct SBMemoryRegionInfoListIter<'d> {
memory_list: &'d SBMemoryRegionInfoList,
idx: u32,
}

impl<'d> Iterator for SBMemoryRegionInfoListIter<'d> {
type Item = SBMemoryRegionInfo;

#[allow(missing_docs)]
fn next(&mut self) -> Option<SBMemoryRegionInfo> {
if self.idx < self.memory_list.get_size() {
let r = self.memory_list.get_memory_region(self.idx);
self.idx += 1;
r
} else {
None
}
}

#[allow(missing_docs)]
fn size_hint(&self) -> (usize, Option<usize>) {
let sz = self.memory_list.get_size() as usize;
(sz - self.idx as usize, Some(sz))
}
}
28 changes: 25 additions & 3 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
// except according to those terms.

use crate::{
lldb_pid_t, lldb_tid_t, sys, SBBroadcaster, SBError, SBEvent, SBProcessInfo, SBQueue, SBStream,
SBThread, StateType,
lldb_addr_t, lldb_pid_t, lldb_tid_t, sys, SBBroadcaster, SBError, SBEvent, SBMemoryRegionInfo,
SBMemoryRegionInfoList, SBProcessInfo, SBQueue, SBStream, SBThread, StateType,
};
use std::ffi::{CStr, CString};
use std::ffi::{c_void, CStr, CString};
use std::fmt;

/// The process associated with the target program.
Expand Down Expand Up @@ -338,6 +338,28 @@ impl SBProcess {
pub fn process_info(&self) -> SBProcessInfo {
SBProcessInfo::from(unsafe { sys::SBProcessGetProcessInfo(self.raw) })
}

#[allow(missing_docs)]
pub fn get_memory_region_info(
&self,
load_addr: lldb_addr_t,
) -> Result<SBMemoryRegionInfo, SBError> {
let region_info = SBMemoryRegionInfo::default();
let error = SBError::from(unsafe {
sys::SBProcessGetMemoryRegionInfo(self.raw, load_addr, region_info.raw)
});

if error.is_success() {
Ok(region_info)
} else {
Err(error)
}
}

#[allow(missing_docs)]
pub fn get_memory_regions(&self) -> SBMemoryRegionInfoList {
SBMemoryRegionInfoList::from(unsafe { sys::SBProcessGetMemoryRegions(self.raw) })
}
}

/// Iterate over the [threads] in a [process].
Expand Down
20 changes: 20 additions & 0 deletions src/target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,26 @@ impl SBTarget {
unsafe { sys::SBTargetDeleteAllBreakpoints(self.raw) };
}

#[allow(missing_docs)]
pub fn breakpoint_create_by_location(&self, file: &str, line: u32) -> SBBreakpoint {
let file = CString::new(file).unwrap();
SBBreakpoint::from(unsafe {
sys::SBTargetBreakpointCreateByLocation(self.raw, file.as_ptr(), line)
})
}

#[allow(missing_docs)]
pub fn breakpoint_create_by_address(&self, address: lldb_addr_t) -> SBBreakpoint {
SBBreakpoint::from(unsafe { sys::SBTargetBreakpointCreateByAddress(self.raw, address) })
}

#[allow(missing_docs)]
pub fn breakpoint_create_by_sbaddress(&self, address: SBAddress) -> SBBreakpoint {
SBBreakpoint::from(unsafe {
sys::SBTargetBreakpointCreateBySBAddress(self.raw, address.raw)
})
}

#[allow(missing_docs)]
pub fn breakpoints(&self) -> SBTargetBreakpointIter {
SBTargetBreakpointIter {
Expand Down
23 changes: 23 additions & 0 deletions src/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
};
use std::ffi::CStr;
use std::fmt;
use RunMode;

/// A thread of execution.
///
Expand Down Expand Up @@ -223,6 +224,28 @@ impl SBThread {
SBProcess::from(unsafe { sys::SBThreadGetProcess(self.raw) })
}

#[allow(missing_docs)]
pub fn step_out(&self) -> Result<(), SBError> {
let error = SBError::default();
unsafe { sys::SBThreadStepOut(self.raw, error.raw) }
if error.is_success() {
Ok(())
} else {
Err(error)
}
}

#[allow(missing_docs)]
pub fn step_over(&self, stop_other_threads: RunMode) -> Result<(), SBError> {
let error = SBError::default();
unsafe { sys::SBThreadStepOver(self.raw, stop_other_threads, error.raw) }
if error.is_success() {
Ok(())
} else {
Err(error)
}
}

/// If the given event is a thread event, return it as an
/// `SBThreadEvent`. Otherwise, return `None`.
pub fn event_as_thread_event(event: &SBEvent) -> Option<SBThreadEvent> {
Expand Down
Loading