servo/ports/servoshell/backtrace.rs
Jonathan Schwender 9455169813
Add OpenHarmony support to servoshell (#32594)
* Generate EGL bindings for ohos

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Adjust servoshell `bin` error message for android/ohos

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* ohos: disable WebGL

offscreen buffers are not implemented yet on ohos.

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Add OpenHarmony support to servoshell

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Share ResourceReaderInstance

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Share android/ohos HostTrait

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Share servo glue

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>

* Pass Init options from ArkTS to Servo

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* f rebase ResourceReaderMethods

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* fixup! Share ResourceReaderInstance

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Fix typo

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Update Cargo.lock

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* ohos: Move WebGL check to webgl thread

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Remove commented code

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

* Remove commented and duplicate / unused code

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>

---------

Signed-off-by: Jonathan Schwender <jonathan.schwender@huawei.com>
Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
2024-06-28 12:51:50 +00:00

117 lines
3.7 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! Similar to `println!("{:?}", Backtrace::new())`, but doesnt allocate.
//!
//! Seems to fix some deadlocks: <https://github.com/servo/servo/issues/24881>
//!
//! FIXME: if/when a future version of the `backtrace` crate has
//! <https://github.com/rust-lang/backtrace-rs/pull/265>, use that instead.
use std::fmt::{self, Write};
use backtrace::{BytesOrWideString, PrintFmt};
#[inline(never)]
pub(crate) fn print(w: &mut dyn std::io::Write) -> Result<(), std::io::Error> {
write!(
w,
"{:?}",
Print {
print_fn_address: print as usize,
}
)
}
#[cfg(target_env = "ohos")]
pub(crate) fn print_ohos() {
// Print to `hilog`
log::error!(
"{:?}",
Print {
print_fn_address: print as usize,
}
)
}
struct Print {
print_fn_address: usize,
}
impl fmt::Debug for Print {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
// Safety: were in a signal handler that is about to call `libc::_exit`.
// Potential data races from using `*_unsynchronized` functions are perhaps
// less bad than potential deadlocks?
unsafe {
let mut print_fn_frame = 0;
let mut frame_count = 0;
backtrace::trace_unsynchronized(|frame| {
let found = frame.symbol_address() as usize == self.print_fn_address;
if found {
print_fn_frame = frame_count;
}
frame_count += 1;
!found
});
let mode = PrintFmt::Short;
let mut p = print_path;
let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
f.add_context()?;
let mut result = Ok(());
let mut frame_count = 0;
backtrace::trace_unsynchronized(|frame| {
let skip = frame_count < print_fn_frame;
frame_count += 1;
if skip {
return true;
}
let mut frame_fmt = f.frame();
let mut any_symbol = false;
backtrace::resolve_frame_unsynchronized(frame, |symbol| {
any_symbol = true;
if let Err(e) = frame_fmt.symbol(frame, symbol) {
result = Err(e)
}
});
if !any_symbol {
if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) {
result = Err(e)
}
}
result.is_ok()
});
result?;
f.finish()
}
}
}
fn print_path(fmt: &mut fmt::Formatter<'_>, path: BytesOrWideString<'_>) -> fmt::Result {
match path {
BytesOrWideString::Bytes(mut bytes) => loop {
match std::str::from_utf8(bytes) {
Ok(s) => {
fmt.write_str(s)?;
break;
},
Err(err) => {
fmt.write_char(std::char::REPLACEMENT_CHARACTER)?;
match err.error_len() {
Some(len) => bytes = &bytes[err.valid_up_to() + len..],
None => break,
}
},
}
},
BytesOrWideString::Wide(wide) => {
for c in std::char::decode_utf16(wide.iter().cloned()) {
fmt.write_char(c.unwrap_or(std::char::REPLACEMENT_CHARACTER))?
}
},
}
Ok(())
}