deno_panic 0.2.0

stack trace and symbolication for deno
Documentation
use std::io::Cursor;

use symbolic::{
  common::ByteView,
  debuginfo::Archive,
  symcache::{SymCache, SymCacheConverter},
};
use symbolic_demangle::{Demangle, DemangleOptions};

use crate::vlq;

pub fn create_symcache(debug_file: &[u8]) -> Result<Vec<u8>, anyhow::Error> {
  let byteview = ByteView::from_slice(debug_file);
  let fat_obj = Archive::parse(&byteview)?;
  let objects: Result<Vec<_>, _> = fat_obj.objects().collect();
  let objects = objects?;
  if objects.len() != 1 {
    anyhow::bail!("Fat archives are not supported currently");
  }
  let object = &objects[0];
  let mut converter = SymCacheConverter::new();
  converter.process_object(object)?;

  let mut result = Vec::new();
  converter.serialize(&mut Cursor::new(&mut result))?;
  Ok(result)
}

#[derive(serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FrameLocation {
  pub demangled_name: String,
  pub name: String,
  pub language: String,
  pub full_path: String,
  pub line: u32,
}

pub fn symbolicate_addrs<B: Iterator<Item = u8>>(
  addrs: &mut B,
  symcache: &[u8],
) -> Result<Vec<Vec<FrameLocation>>, anyhow::Error> {
  let symcache = SymCache::parse(symcache)?;
  let mut out = Vec::new();
  loop {
    let addr = match vlq::vlq_decode(addrs) {
      Ok(addr) => addr,
      Err(_) => break,
    };

    let syms = symcache.lookup(addr as u64).collect::<Vec<_>>();
    out.push(
      syms
        .into_iter()
        .map(|sym| FrameLocation {
          demangled_name: sym
            .function()
            .name_for_demangling()
            .try_demangle(DemangleOptions::name_only())
            .into_owned(),
          name: sym.function().name().into(),
          language: sym.function().language().to_string(),
          full_path: sym
            .file()
            .map(|file| file.full_path())
            .unwrap_or_else(|| "<unknown file>".into()),
          line: sym.line(),
        })
        .collect(),
    );
  }

  Ok(out)
}