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

Simplify sqlite deps-graph of symbolizer #377

Merged
merged 1 commit into from
Jun 10, 2024
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
479 changes: 252 additions & 227 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions support/addr2line/.cargo/config.toml

This file was deleted.

15 changes: 6 additions & 9 deletions support/addr2line/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "playdate-symbolize"
version = "0.1.1"
version = "0.1.2"
readme = "README.md"
description = "Tools for symbolise addresses from bin (pdex.elf) and Playdate's trace or crashlog."
keywords = ["playdate", "bin", "elf", "addr2line", "utility"]
Expand All @@ -10,7 +10,6 @@ license.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
build = "src/build.rs"


[[bin]]
Expand Down Expand Up @@ -48,12 +47,9 @@ features = ["std", "env", "derive", "help", "usage", "color"]
workspace = true
optional = true

[dependencies.sqlx]
version = "0.7"
# TODO: support runtime-async-std
features = ["runtime-tokio", "sqlite", "macros"]
default-features = false

[dependencies.rusqlite]
version = "0.30"
features = ["bundled"]

[dependencies.utils]
features = ["log"]
Expand All @@ -62,4 +58,5 @@ workspace = true


[features]
default = ["clap", "env_logger", "const-str"]
default = ["clap", "env_logger", "const-str", "sqlite-bundled"]
sqlite-bundled = ["rusqlite/bundled"]
2 changes: 1 addition & 1 deletion support/addr2line/src/addr2line-crashlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ async fn main() -> anyhow::Result<()> {
}
debug!("Resolved addresses: {}", resolved_addrs.len());

os_db.close().await;
os_db.close().await?;

let docs: Vec<_> = docs.into_iter()
.map(|doc| {
Expand Down
2 changes: 1 addition & 1 deletion support/addr2line/src/addr2line-trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ async fn process_trace<R: AsyncRead>(reader: R,
}
}

os_db.close().await;
os_db.close().await?;

info!("Resolved addresses: {resolved}");
info!("Unknown addresses: {missed}");
Expand Down
2 changes: 1 addition & 1 deletion support/addr2line/src/addr2line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ async fn main() -> anyhow::Result<()> {
}
}

os_db.close().await;
os_db.close().await?;

Ok(())
}
Expand Down
22 changes: 0 additions & 22 deletions support/addr2line/src/build.rs

This file was deleted.

110 changes: 59 additions & 51 deletions support/addr2line/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf};
use std::io::{Error as IoError, ErrorKind as IoErrorKind};

use anyhow::Result;
use sqlx::{Executor, Pool, Sqlite, SqlitePool};
use rusqlite::Connection;
use symbolic::common::{Language, Name, NameMangling};
use utils::toolchain::sdk::Sdk;

Expand All @@ -16,7 +16,7 @@ const QUERY_LN: &str = include_str!("query-ln.sql");


pub struct Resolver {
pool: Pool<Sqlite>,
conn: Connection,
}

impl Resolver {
Expand All @@ -38,14 +38,16 @@ impl Resolver {
}

pub async fn with_exact(db_path: &Path) -> Result<Self> {
let db_url = format!("sqlite://{}", db_path.display());
let pool = SqlitePool::connect(&db_url).await?;
trace!("query fn prepared: {}", pool.prepare(QUERY_FN).await.is_ok());
trace!("query ln prepared: {}", pool.prepare(QUERY_LN).await.is_ok());
Ok(Self { pool })
let conn = Connection::open(db_path)?;
Ok(Self { conn })
}

pub async fn close(&self) { self.pool.close().await }
pub async fn close(self) -> rusqlite::Result<()> {
self.conn.close().map_err(|(conn, err)| {
conn.close().ok();
err
})
}


pub async fn resolve(&self, addr: u32) -> anyhow::Result<report::Report> {
Expand Down Expand Up @@ -86,28 +88,33 @@ impl Resolver {
}

pub async fn resolve_fn(&self, addr: u32) -> anyhow::Result<report::Report> {
#[cfg(query_validation)] // build with RUSTFLAGS='--cfg query_validation'
let recs = sqlx::query_file!("src/query-fn.sql", addr).fetch_all(&self.pool);
#[cfg(not(query_validation))]
let recs = {
#[derive(sqlx::FromRow)]
struct Record {
name: Option<String>,
low: Option<i64>,
size: Option<i64>,
fn_hw_id: Option<i64>,
ln_low: Option<i64>,
ln_hw_id: Option<i64>,
lineno: Option<i64>,
path: Option<String>,
}
sqlx::query_as::<_, Record>(QUERY_FN).bind(addr)
.fetch_all(&self.pool)
};
struct Record {
name: Option<String>,
low: Option<i64>,
size: Option<i64>,
fn_hw_id: Option<i64>,
ln_low: Option<i64>,
ln_hw_id: Option<i64>,
lineno: Option<i64>,
path: Option<String>,
}

let mut stmt = self.conn.prepare(QUERY_FN)?;
let records = stmt.query_map([addr], |row| {
Ok(Record { name: row.get(0)?,
low: row.get(1)?,
size: row.get(2)?,
fn_hw_id: row.get(3)?,
ln_low: row.get(4)?,
ln_hw_id: row.get(4)?,
lineno: row.get(6)?,
path: row.get(7)? })
})?;

let mut results = HashMap::new();

for func in recs.await? {
for record in records {
let func = record?;
let fn_name = func.name.as_deref().map(Cow::from).unwrap_or(UNKNOWN.into());
let fn_id = format_args!("{fn_name}{}", func.fn_hw_id.unwrap_or_default()).to_string();
let name = Name::new(fn_name.to_string(), NameMangling::Unmangled, Language::C);
Expand Down Expand Up @@ -140,31 +147,32 @@ impl Resolver {


pub async fn resolve_ln(&self, addr: u32) -> anyhow::Result<report::Report> {
#[cfg(query_validation)] // build with RUSTFLAGS='--cfg query_validation'
let recs = sqlx::query_file!("src/query-ln.sql", addr).fetch_all(&self.pool);
#[cfg(not(query_validation))]
let recs = {
#[derive(sqlx::FromRow)]
struct Record {
low: Option<i64>,
hw_id: Option<i64>,
lineno: Option<i64>,
path: Option<String>,
}
sqlx::query_as::<_, Record>(QUERY_LN).bind(addr)
.fetch_all(&self.pool)
};
struct Record {
low: Option<i64>,
hw_id: Option<i64>,
lineno: Option<i64>,
path: Option<String>,
}

let mut lines: Vec<_> = recs.await?
.into_iter()
.map(|ln| {
report::Span { hw_id: ln.hw_id,
address: ln.low.map(|p| p as _).unwrap_or_default(),
size: None,
line: ln.lineno.map(|p| p as _),
file: ln.path.unwrap_or(UNKNOWN.into()).into() }
})
.collect();
let mut stmt = self.conn.prepare(QUERY_LN)?;
let records = stmt.query_map([addr], |row| {
Ok(Record { low: row.get(0)?,
hw_id: row.get(1)?,
lineno: row.get(2)?,
path: row.get(3)? })
})?;

let mut lines = records.into_iter()
.try_fold(Vec::new(), |mut acc, res| -> rusqlite::Result<_> {
let ln = res?;
let span = report::Span { hw_id: ln.hw_id,
address: ln.low.map(|p| p as _).unwrap_or_default(),
size: None,
line: ln.lineno.map(|p| p as _),
file: ln.path.unwrap_or(UNKNOWN.into()).into() };
acc.push(span);
Ok(acc)
})?;

let result = if lines.is_empty() {
report::Report { addr: (addr as u64).into(),
Expand Down
Loading