diff options
author | Alan Jeffrey <ajeffrey@mozilla.com> | 2016-07-11 14:09:54 -0500 |
---|---|---|
committer | Alan Jeffrey <ajeffrey@mozilla.com> | 2016-07-20 21:56:43 -0500 |
commit | c889900cff2cde40d21fa27810b9c4b0b57c390a (patch) | |
tree | 5b2988473f32ebefa4af1c73f4e417fb99a51c0f | |
parent | b34b30fd96e29f9c3773c9146c78e3d47fdc156d (diff) | |
download | servo-c889900cff2cde40d21fa27810b9c4b0b57c390a.tar.gz servo-c889900cff2cde40d21fa27810b9c4b0b57c390a.zip |
Removed panic channel, replaced by integrated logging and issue reporting.
22 files changed, 85 insertions, 251 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index af6237ddd8b..d2152d52cfe 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -29,7 +29,6 @@ use msg::constellation_msg::{FrameId, FrameType, PipelineId}; use msg::constellation_msg::{Key, KeyModifiers, KeyState, LoadData}; use msg::constellation_msg::{PipelineNamespace, PipelineNamespaceId, NavigationDirection}; use msg::constellation_msg::{SubpageId, WindowSizeType}; -use msg::constellation_msg::{self, PanicMsg}; use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::filemanager_thread::FileManagerThreadMsg; use net_traits::image_cache_thread::ImageCacheThread; @@ -91,9 +90,6 @@ pub struct Constellation<Message, LTF, STF> { /// A channel through which layout thread messages can be sent to this object. layout_sender: IpcSender<FromLayoutMsg>, - /// A channel through which panic messages can be sent to this object. - panic_sender: IpcSender<PanicMsg>, - /// Receives messages from scripts. script_receiver: Receiver<FromScriptMsg>, @@ -103,9 +99,6 @@ pub struct Constellation<Message, LTF, STF> { /// Receives messages from the layout thread layout_receiver: Receiver<FromLayoutMsg>, - /// Receives panic messages. - panic_receiver: Receiver<PanicMsg>, - /// A channel (the implementation of which is port-specific) through which messages can be sent /// to the compositor. compositor_proxy: Box<CompositorProxy>, @@ -189,9 +182,6 @@ pub struct Constellation<Message, LTF, STF> { /// Are we shutting down? shutting_down: bool, - /// Have we seen any panics? Hopefully always false! - handled_panic: bool, - /// Have we seen any warnings? Hopefully always empty! /// The buffer contains `(thread_name, reason)` entries. handled_warnings: VecDeque<(Option<String>, String)>, @@ -346,9 +336,10 @@ impl Log for FromScriptLogger { fn log(&self, record: &LogRecord) { if let Some(entry) = log_entry(record) { - // TODO: Store the pipeline id in TLS so we can recover it here + debug!("Sending log entry {:?}.", entry); + let pipeline_id = PipelineId::installed(); let thread_name = thread::current().name().map(ToOwned::to_owned); - let msg = FromScriptMsg::LogEntry(None, thread_name, entry); + let msg = FromScriptMsg::LogEntry(pipeline_id, thread_name, entry); if let Ok(chan) = self.constellation_chan.lock() { let _ = chan.send(msg); } @@ -384,9 +375,10 @@ impl Log for FromCompositorLogger { fn log(&self, record: &LogRecord) { if let Some(entry) = log_entry(record) { - // TODO: Store the pipeline id in TLS so we can recover it here + debug!("Sending log entry {:?}.", entry); + let pipeline_id = PipelineId::installed(); let thread_name = thread::current().name().map(ToOwned::to_owned); - let msg = FromCompositorMsg::LogEntry(None, thread_name, entry); + let msg = FromCompositorMsg::LogEntry(pipeline_id, thread_name, entry); if let Ok(chan) = self.constellation_chan.lock() { let _ = chan.send(msg); } @@ -430,19 +422,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> let (ipc_layout_sender, ipc_layout_receiver) = ipc::channel().expect("ipc channel failure"); let layout_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_layout_receiver); - let (ipc_panic_sender, ipc_panic_receiver) = ipc::channel().expect("ipc channel failure"); - let panic_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(ipc_panic_receiver); - let swmanager_receiver = ROUTER.route_ipc_receiver_to_new_mpsc_receiver(swmanager_receiver); let mut constellation: Constellation<Message, LTF, STF> = Constellation { script_sender: ipc_script_sender, layout_sender: ipc_layout_sender, script_receiver: script_receiver, - panic_sender: ipc_panic_sender, compositor_receiver: compositor_receiver, layout_receiver: layout_receiver, - panic_receiver: panic_receiver, compositor_proxy: state.compositor_proxy, devtools_chan: state.devtools_chan, bluetooth_thread: state.bluetooth_thread, @@ -478,7 +465,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> document_states: HashMap::new(), webrender_api_sender: state.webrender_api_sender, shutting_down: false, - handled_panic: false, handled_warnings: VecDeque::new(), random_pipeline_closure: opts::get().random_pipeline_closure_probability.map(|prob| { let seed = opts::get().random_pipeline_closure_seed.unwrap_or_else(random); @@ -539,7 +525,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> parent_info: parent_info, constellation_chan: self.script_sender.clone(), layout_to_constellation_chan: self.layout_sender.clone(), - panic_chan: self.panic_sender.clone(), scheduler_chan: self.scheduler_chan.clone(), compositor_proxy: self.compositor_proxy.clone_compositor_proxy(), devtools_chan: self.devtools_chan.clone(), @@ -617,8 +602,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> Script(FromScriptMsg), Compositor(FromCompositorMsg), Layout(FromLayoutMsg), - Panic(PanicMsg), - FromSWManager(SWManagerMsg) + FromSWManager(SWManagerMsg), } // Get one incoming request. @@ -636,7 +620,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> let receiver_from_script = &self.script_receiver; let receiver_from_compositor = &self.compositor_receiver; let receiver_from_layout = &self.layout_receiver; - let receiver_from_panic = &self.panic_receiver; let receiver_from_swmanager = &self.swmanager_receiver; select! { msg = receiver_from_script.recv() => @@ -645,8 +628,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> Request::Compositor(msg.expect("Unexpected compositor channel panic in constellation")), msg = receiver_from_layout.recv() => Request::Layout(msg.expect("Unexpected layout channel panic in constellation")), - msg = receiver_from_panic.recv() => - Request::Panic(msg.expect("Unexpected panic channel panic in constellation")), msg = receiver_from_swmanager.recv() => Request::FromSWManager(msg.expect("Unexpected panic channel panic in constellation")) } @@ -662,9 +643,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> Request::Layout(message) => { self.handle_request_from_layout(message); }, - Request::Panic(message) => { - self.handle_request_from_panic(message); - }, Request::FromSWManager(message) => { self.handle_request_from_swmanager(message); } @@ -957,15 +935,6 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> } } - fn handle_request_from_panic(&mut self, message: PanicMsg) { - match message { - (pipeline_id, panic_reason, backtrace) => { - debug!("handling panic message ({:?})", pipeline_id); - self.handle_panic(pipeline_id, panic_reason, backtrace); - } - } - } - fn handle_register_serviceworker(&self, scope_things: ScopeThings, scope: Url) { if let Some(ref mgr) = self.swmanager_chan { let _ = mgr.send(ServiceWorkerMsg::RegisterServiceWorker(scope_things, scope)); @@ -1053,22 +1022,14 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> fn handle_send_error(&mut self, pipeline_id: PipelineId, err: IOError) { // Treat send error the same as receiving a panic message debug!("Pipeline {:?} send error ({}).", pipeline_id, err); - self.handle_panic(Some(pipeline_id), format!("Send failed ({})", err), String::from("<none>")); + self.handle_panic(Some(pipeline_id), format!("Send failed ({})", err), None); } - fn handle_panic(&mut self, pipeline_id: Option<PipelineId>, reason: String, backtrace: String) { - error!("Panic: {}", reason); - if !self.handled_panic || opts::get().full_backtraces { - // For the first panic, we print the full backtrace - error!("Backtrace:\n{}", backtrace); - } else { - error!("Backtrace skipped (run with -Z full-backtraces to see every backtrace)."); - } - + fn handle_panic(&mut self, pipeline_id: Option<PipelineId>, reason: String, backtrace: Option<String>) { if opts::get().hard_fail { // It's quite difficult to make Servo exit cleanly if some threads have failed. // Hard fail exists for test runners so we crash and that's good enough. - error!("Pipeline failed in hard-fail mode. Crashing!"); + println!("Pipeline failed in hard-fail mode. Crashing!\n{}\n{}", reason, backtrace.unwrap_or_default()); process::exit(1); } @@ -1109,13 +1070,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> self.push_pending_frame(new_pipeline_id, Some(pipeline_id)); } - - self.handled_panic = true; } fn handle_log_entry(&mut self, pipeline_id: Option<PipelineId>, thread_name: Option<String>, entry: LogEntry) { + debug!("Received log entry {:?}.", entry); match entry { - LogEntry::Panic(reason, backtrace) => self.trigger_mozbrowsererror(pipeline_id, reason, backtrace), + LogEntry::Panic(reason, backtrace) => self.handle_panic(pipeline_id, reason, Some(backtrace)), LogEntry::Error(reason) | LogEntry::Warn(reason) => { // VecDeque::truncate is unstable if WARNINGS_BUFFER_SIZE <= self.handled_warnings.len() { @@ -1439,7 +1399,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> fn handle_navigate_msg(&mut self, pipeline_info: Option<(PipelineId, SubpageId)>, - direction: constellation_msg::NavigationDirection) { + direction: NavigationDirection) { debug!("received message to navigate {:?}", direction); // Get the frame id associated with the pipeline that sent @@ -2310,7 +2270,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> // https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsererror // Note that this does not require the pipeline to be an immediate child of the root - fn trigger_mozbrowsererror(&mut self, pipeline_id: Option<PipelineId>, reason: String, backtrace: String) { + fn trigger_mozbrowsererror(&mut self, pipeline_id: Option<PipelineId>, reason: String, backtrace: Option<String>) { if !PREFS.is_mozbrowser_enabled() { return; } let mut report = String::new(); @@ -2325,10 +2285,12 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF> } report.push_str("\nERROR: "); report.push_str(&*reason); - report.push_str("\n\n"); - report.push_str(&*backtrace); + if let Some(backtrace) = backtrace { + report.push_str("\n\n"); + report.push_str(&*backtrace); + } - let event = MozBrowserEvent::Error(MozBrowserErrorType::Fatal, Some(reason), Some(report)); + let event = MozBrowserEvent::Error(MozBrowserErrorType::Fatal, reason, report); if let Some(pipeline_id) = pipeline_id { if let Some((ancestor_id, subpage_id)) = self.get_mozbrowser_ancestor_info(pipeline_id) { diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs index 45edc40ae2a..dd2a665f6ac 100644 --- a/components/constellation/pipeline.rs +++ b/components/constellation/pipeline.rs @@ -17,7 +17,7 @@ use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; use layers::geometry::DevicePixel; use layout_traits::LayoutThreadFactory; -use msg::constellation_msg::{FrameId, FrameType, LoadData, PanicMsg, PipelineId}; +use msg::constellation_msg::{FrameId, FrameType, LoadData, PipelineId}; use msg::constellation_msg::{PipelineNamespaceId, SubpageId}; use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::image_cache_thread::ImageCacheThread; @@ -89,8 +89,6 @@ pub struct InitialPipelineState { pub constellation_chan: IpcSender<ScriptMsg>, /// A channel for the layout thread to send messages to the constellation. pub layout_to_constellation_chan: IpcSender<LayoutMsg>, - /// A channel to report panics - pub panic_chan: IpcSender<PanicMsg>, /// A channel to schedule timer events. pub scheduler_chan: IpcSender<TimerEventRequest>, /// A channel to the compositor. @@ -159,7 +157,6 @@ impl Pipeline { frame_type: frame_type, load_data: state.load_data.clone(), paint_chan: layout_to_paint_chan.clone().to_opaque(), - panic_chan: state.panic_chan.clone(), pipeline_port: pipeline_port, layout_to_constellation_chan: state.layout_to_constellation_chan.clone(), content_process_shutdown_chan: layout_content_process_shutdown_chan.clone(), @@ -182,7 +179,6 @@ impl Pipeline { layout_to_paint_port, chrome_to_paint_port, state.compositor_proxy.clone_compositor_proxy(), - state.panic_chan.clone(), state.font_cache_thread.clone(), state.time_profiler_chan.clone(), state.mem_profiler_chan.clone()); @@ -234,7 +230,6 @@ impl Pipeline { layout_to_constellation_chan: state.layout_to_constellation_chan, script_chan: script_chan.clone(), load_data: state.load_data.clone(), - panic_chan: state.panic_chan, script_port: script_port, opts: (*opts::get()).clone(), prefs: PREFS.cloned(), @@ -426,7 +421,6 @@ pub struct UnprivilegedPipelineContent { window_size: Option<WindowSizeData>, script_chan: IpcSender<ConstellationControlMsg>, load_data: LoadData, - panic_chan: IpcSender<PanicMsg>, script_port: IpcReceiver<ConstellationControlMsg>, layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>, opts: Opts, @@ -452,7 +446,6 @@ impl UnprivilegedPipelineContent { control_port: self.script_port, constellation_chan: self.constellation_chan, scheduler_chan: self.scheduler_chan, - panic_chan: self.panic_chan.clone(), bluetooth_thread: self.bluetooth_thread, resource_threads: self.resource_threads, image_cache_thread: self.image_cache_thread.clone(), @@ -470,7 +463,6 @@ impl UnprivilegedPipelineContent { layout_pair, self.pipeline_port, self.layout_to_constellation_chan, - self.panic_chan, self.script_chan, self.layout_to_paint_chan, self.image_cache_thread, diff --git a/components/gfx/paint_thread.rs b/components/gfx/paint_thread.rs index aa759ca6b7a..b4ad2abd299 100644 --- a/components/gfx/paint_thread.rs +++ b/components/gfx/paint_thread.rs @@ -17,10 +17,9 @@ use font_cache_thread::FontCacheThread; use font_context::FontContext; use gfx_traits::{ChromeToPaintMsg, Epoch, LayerId, LayerKind, LayerProperties}; use gfx_traits::{PaintListener, PaintRequest, StackingContextId}; -use ipc_channel::ipc::IpcSender; use layers::layers::{BufferRequest, LayerBuffer, LayerBufferSet}; use layers::platform::surface::{NativeDisplay, NativeSurface}; -use msg::constellation_msg::{PanicMsg, PipelineId}; +use msg::constellation_msg::PipelineId; use paint_context::PaintContext; use profile_traits::mem; use profile_traits::time; @@ -377,13 +376,14 @@ impl<C> PaintThread<C> where C: PaintListener + Send + 'static { layout_to_paint_port: Receiver<LayoutToPaintMsg>, chrome_to_paint_port: Receiver<ChromeToPaintMsg>, mut compositor: C, - panic_chan: IpcSender<PanicMsg>, font_cache_thread: FontCacheThread, time_profiler_chan: time::ProfilerChan, mem_profiler_chan: mem::ProfilerChan) { - thread::spawn_named_with_send_on_panic(format!("PaintThread {:?}", id), - thread_state::PAINT, - move || { + thread::spawn_named(format!("PaintThread {:?}", id), + move || { + thread_state::initialize(thread_state::PAINT); + PipelineId::install(id); + let native_display = compositor.native_display(); let worker_threads = WorkerThreadProxy::spawn(native_display, font_cache_thread, @@ -412,7 +412,7 @@ impl<C> PaintThread<C> where C: PaintListener + Send + 'static { for worker_thread in &mut paint_thread.worker_threads { worker_thread.exit() } - }, Some(id), panic_chan); + }); } #[allow(unsafe_code)] diff --git a/components/layout_thread/lib.rs b/components/layout_thread/lib.rs index 592a6cda6a4..9d576e3bd02 100644 --- a/components/layout_thread/lib.rs +++ b/components/layout_thread/lib.rs @@ -76,7 +76,7 @@ use layout::traversal::RecalcStyleAndConstructFlows; use layout::webrender_helpers::{WebRenderDisplayListConverter, WebRenderFrameBuilder}; use layout::wrapper::{LayoutNodeLayoutData, NonOpaqueStyleAndLayoutData}; use layout_traits::LayoutThreadFactory; -use msg::constellation_msg::{PanicMsg, PipelineId}; +use msg::constellation_msg::PipelineId; use net_traits::image_cache_thread::UsePlaceholder; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; use profile_traits::mem::{self, Report, ReportKind, ReportsChan}; @@ -244,7 +244,6 @@ impl LayoutThreadFactory for LayoutThread { chan: (Sender<Msg>, Receiver<Msg>), pipeline_port: IpcReceiver<LayoutControlMsg>, constellation_chan: IpcSender<ConstellationMsg>, - panic_chan: IpcSender<PanicMsg>, script_chan: IpcSender<ConstellationControlMsg>, paint_chan: OptionalIpcSender<LayoutToPaintMsg>, image_cache_thread: ImageCacheThread, @@ -253,9 +252,10 @@ impl LayoutThreadFactory for LayoutThread { mem_profiler_chan: mem::ProfilerChan, content_process_shutdown_chan: IpcSender<()>, webrender_api_sender: Option<webrender_traits::RenderApiSender>) { - thread::spawn_named_with_send_on_panic(format!("LayoutThread {:?}", id), - thread_state::LAYOUT, - move || { + thread::spawn_named(format!("LayoutThread {:?}", id), + move || { + thread_state::initialize(thread_state::LAYOUT); + PipelineId::install(id); { // Ensures layout thread is destroyed before we send shutdown message let sender = chan.0; let layout = LayoutThread::new(id, @@ -278,7 +278,7 @@ impl LayoutThreadFactory for LayoutThread { }, reporter_name, sender, Msg::CollectReports); } let _ = content_process_shutdown_chan.send(()); - }, Some(id), panic_chan); + }); } } @@ -747,7 +747,6 @@ impl LayoutThread { info.layout_pair, info.pipeline_port, info.constellation_chan, - info.panic_chan, info.script_chan.clone(), info.paint_chan.to::<LayoutToPaintMsg>(), self.image_cache_thread.clone(), diff --git a/components/layout_traits/lib.rs b/components/layout_traits/lib.rs index ad91999cc30..1b6c621d755 100644 --- a/components/layout_traits/lib.rs +++ b/components/layout_traits/lib.rs @@ -22,7 +22,7 @@ extern crate webrender_traits; use gfx::font_cache_thread::FontCacheThread; use gfx::paint_thread::LayoutToPaintMsg; use ipc_channel::ipc::{IpcReceiver, IpcSender}; -use msg::constellation_msg::{PanicMsg, PipelineId}; +use msg::constellation_msg::PipelineId; use net_traits::image_cache_thread::ImageCacheThread; use profile_traits::{mem, time}; use script_traits::LayoutMsg as ConstellationMsg; @@ -41,7 +41,6 @@ pub trait LayoutThreadFactory { chan: (Sender<Self::Message>, Receiver<Self::Message>), pipeline_port: IpcReceiver<LayoutControlMsg>, constellation_chan: IpcSender<ConstellationMsg>, - panic_chan: IpcSender<PanicMsg>, script_chan: IpcSender<ConstellationControlMsg>, layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>, image_cache_thread: ImageCacheThread, diff --git a/components/msg/constellation_msg.rs b/components/msg/constellation_msg.rs index 7872e5983d2..235676f0d60 100644 --- a/components/msg/constellation_msg.rs +++ b/components/msg/constellation_msg.rs @@ -13,8 +13,6 @@ use std::fmt; use url::Url; use webrender_traits; -pub type PanicMsg = (Option<PipelineId>, String, String); - #[derive(Deserialize, Eq, PartialEq, Serialize, Copy, Clone, HeapSizeOf)] pub enum WindowSizeType { Initial, @@ -269,6 +267,8 @@ impl PipelineNamespace { thread_local!(pub static PIPELINE_NAMESPACE: Cell<Option<PipelineNamespace>> = Cell::new(None)); +thread_local!(pub static PIPELINE_ID: Cell<Option<PipelineId>> = Cell::new(None)); + #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)] pub struct PipelineNamespaceId(pub u32); @@ -308,6 +308,15 @@ impl PipelineId { let PipelineIndex(index) = self.index; webrender_traits::PipelineId(namespace_id, index) } + + pub fn install(id: PipelineId) { + PIPELINE_ID.with(|tls| tls.set(Some(id))) + } + + pub fn installed() -> Option<PipelineId> { + PIPELINE_ID.with(|tls| tls.get()) + } + } impl fmt::Display for PipelineId { diff --git a/components/script/dom/bindings/global.rs b/components/script/dom/bindings/global.rs index 5adcbb67818..fe81b8a14de 100644 --- a/components/script/dom/bindings/global.rs +++ b/components/script/dom/bindings/global.rs @@ -18,7 +18,7 @@ use ipc_channel::ipc::IpcSender; use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment}; use js::jsapi::{JSContext, JSObject, JS_GetClass, MutableHandleValue}; use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL}; -use msg::constellation_msg::{PipelineId, PanicMsg}; +use msg::constellation_msg::PipelineId; use net_traits::filemanager_thread::FileManagerThreadMsg; use net_traits::{ResourceThreads, CoreResourceThread, IpcSend}; use profile_traits::{mem, time}; @@ -283,14 +283,6 @@ impl<'a> GlobalRef<'a> { } } - /// Returns an `IpcSender` to report panics on. - pub fn panic_chan(&self) -> &IpcSender<PanicMsg> { - match *self { - GlobalRef::Window(ref window) => window.panic_chan(), - GlobalRef::Worker(ref worker) => worker.panic_chan(), - } - } - /// Returns a wrapper for runnables to ensure they are cancelled if the global /// is being destroyed. pub fn get_runnable_wrapper(&self) -> RunnableWrapper { diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index cf5537676e0..b65fd72ab62 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -38,8 +38,8 @@ use std::sync::atomic::AtomicBool; use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel}; use std::sync::{Arc, Mutex}; use url::Url; -use util::thread::spawn_named_with_send_on_panic; -use util::thread_state::{IN_WORKER, SCRIPT}; +use util::thread::spawn_named; +use util::thread_state; /// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular /// value for the duration of this object's lifetime. This ensures that the related Worker @@ -161,8 +161,10 @@ impl DedicatedWorkerGlobalScope { closing: Arc<AtomicBool>) { let serialized_worker_url = worker_url.to_string(); let name = format!("WebWorker for {}", serialized_worker_url); - let panic_chan = init.panic_chan.clone(); - spawn_named_with_send_on_panic(name, SCRIPT | IN_WORKER, move || { + spawn_named(name, move || { + thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER); + PipelineId::install(id); + let roots = RootCollection::new(); let _stack_roots_tls = StackRootTLS::new(&roots); let (url, source) = match load_whole_resource(LoadContext::Script, @@ -225,7 +227,7 @@ impl DedicatedWorkerGlobalScope { global.handle_event(event); } }, reporter_name, parent_sender, CommonScriptMsg::CollectReports); - }, Some(id.clone()), panic_chan); + }); } pub fn script_chan(&self) -> Box<ScriptChan + Send> { diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs index 1b2001c08df..efd33eecf54 100644 --- a/components/script/dom/htmliframeelement.rs +++ b/components/script/dom/htmliframeelement.rs @@ -353,8 +353,8 @@ unsafe fn build_mozbrowser_event_detail(event: MozBrowserEvent, MozBrowserEvent::Error(error_type, description, report) => { BrowserElementErrorEventDetail { type_: Some(DOMString::from(error_type.name())), - description: description.map(DOMString::from), - report: report.map(DOMString::from), + description: Some(DOMString::from(description)), + report: Some(DOMString::from(report)), version: Some(DOMString::from_string(servo_version().into())), }.to_jsval(cx, rval); }, diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 07509a92e4a..b4984bb2a4a 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -45,7 +45,7 @@ use js::jsapi::{JS_GetRuntime, JS_GC, MutableHandleValue, SetWindowProxy}; use js::rust::CompileOptionsWrapper; use js::rust::Runtime; use libc; -use msg::constellation_msg::{FrameType, LoadData, PanicMsg, PipelineId, SubpageId, WindowSizeType}; +use msg::constellation_msg::{FrameType, LoadData, PipelineId, SubpageId, WindowSizeType}; use net_traits::ResourceThreads; use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread}; @@ -266,9 +266,6 @@ pub struct Window { /// A list of scroll offsets for each scrollable element. scroll_offsets: DOMRefCell<HashMap<UntrustedNodeAddress, Point2D<f32>>>, - - #[ignore_heap_size_of = "Defined in ipc-channel"] - panic_chan: IpcSender<PanicMsg>, } impl Window { @@ -1424,10 +1421,6 @@ impl Window { &self.scheduler_chan } - pub fn panic_chan(&self) -> &IpcSender<PanicMsg> { - &self.panic_chan - } - pub fn schedule_callback(&self, callback: OneshotTimerCallback, duration: MsDuration) -> OneshotTimerHandle { self.timers.schedule_callback(callback, duration, @@ -1623,7 +1616,6 @@ impl Window { constellation_chan: IpcSender<ConstellationMsg>, control_chan: IpcSender<ConstellationControlMsg>, scheduler_chan: IpcSender<TimerEventRequest>, - panic_chan: IpcSender<PanicMsg>, timer_event_chan: IpcSender<TimerEvent>, layout_chan: Sender<Msg>, id: PipelineId, @@ -1693,7 +1685,6 @@ impl Window { ignore_further_async_events: Arc::new(AtomicBool::new(false)), error_reporter: error_reporter, scroll_offsets: DOMRefCell::new(HashMap::new()), - panic_chan: panic_chan, }; WindowBinding::Wrap(runtime.cx(), win) diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index cd8476b49d6..154705fe145 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -23,7 +23,7 @@ use ipc_channel::ipc::IpcSender; use js::jsapi::{HandleValue, JSContext, JSRuntime}; use js::jsval::UndefinedValue; use js::rust::Runtime; -use msg::constellation_msg::{PipelineId, ReferrerPolicy, PanicMsg}; +use msg::constellation_msg::{PipelineId, ReferrerPolicy}; use net_traits::{LoadContext, ResourceThreads, load_whole_resource}; use net_traits::{LoadOrigin, IpcSend}; use profile_traits::{mem, time}; @@ -58,7 +58,6 @@ pub fn prepare_workerscope_init(global: GlobalRef, time_profiler_chan: global.time_profiler_chan().clone(), from_devtools_sender: devtools_sender, constellation_chan: global.constellation_chan().clone(), - panic_chan: global.panic_chan().clone(), scheduler_chan: global.scheduler_chan().clone(), worker_id: worker_id }; @@ -110,9 +109,6 @@ pub struct WorkerGlobalScope { #[ignore_heap_size_of = "Defined in std"] scheduler_chan: IpcSender<TimerEventRequest>, - - #[ignore_heap_size_of = "Defined in ipc-channel"] - panic_chan: IpcSender<PanicMsg>, } impl WorkerGlobalScope { @@ -144,7 +140,6 @@ impl WorkerGlobalScope { devtools_wants_updates: Cell::new(false), constellation_chan: init.constellation_chan, scheduler_chan: init.scheduler_chan, - panic_chan: init.panic_chan, } } @@ -221,10 +216,6 @@ impl WorkerGlobalScope { worker_id } - pub fn panic_chan(&self) -> &IpcSender<PanicMsg> { - &self.panic_chan - } - pub fn get_runnable_wrapper(&self) -> RunnableWrapper { RunnableWrapper { cancelled: self.closing.clone().unwrap(), diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 1a32477b999..cf0cebf5a65 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -64,7 +64,7 @@ use js::jsapi::{JSTracer, SetWindowProxyClass}; use js::jsval::UndefinedValue; use js::rust::Runtime; use mem::heap_size_of_self_and_children; -use msg::constellation_msg::{FrameType, LoadData, PanicMsg, PipelineId, PipelineNamespace}; +use msg::constellation_msg::{FrameType, LoadData, PipelineId, PipelineNamespace}; use msg::constellation_msg::{SubpageId, WindowSizeType, ReferrerPolicy}; use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheResult, ImageCacheThread}; @@ -393,8 +393,6 @@ pub struct ScriptThread { timer_event_port: Receiver<TimerEvent>, content_process_shutdown_chan: IpcSender<()>, - - panic_chan: IpcSender<PanicMsg>, } /// In the event of thread panic, all data on the stack runs its destructor. However, there @@ -441,15 +439,15 @@ impl ScriptThreadFactory for ScriptThread { fn create(state: InitialScriptState, load_data: LoadData) -> (Sender<message::Msg>, Receiver<message::Msg>) { - let panic_chan = state.panic_chan.clone(); let (script_chan, script_port) = channel(); let (sender, receiver) = channel(); let layout_chan = sender.clone(); let pipeline_id = state.id; - thread::spawn_named_with_send_on_panic(format!("ScriptThread {:?}", state.id), - thread_state::SCRIPT, - move || { + thread::spawn_named(format!("ScriptThread {:?}", state.id), + move || { + thread_state::initialize(thread_state::SCRIPT); + PipelineId::install(pipeline_id); PipelineNamespace::install(state.pipeline_namespace_id); let roots = RootCollection::new(); let _stack_roots_tls = StackRootTLS::new(&roots); @@ -479,7 +477,7 @@ impl ScriptThreadFactory for ScriptThread { // This must always be the very last operation performed before the thread completes failsafe.neuter(); - }, Some(pipeline_id), panic_chan); + }); (sender, receiver) } @@ -592,7 +590,6 @@ impl ScriptThread { constellation_chan: state.constellation_chan, time_profiler_chan: state.time_profiler_chan, mem_profiler_chan: state.mem_profiler_chan, - panic_chan: state.panic_chan, devtools_chan: state.devtools_chan, devtools_port: devtools_port, @@ -1142,7 +1139,6 @@ impl ScriptThread { frame_type, load_data, paint_chan, - panic_chan, pipeline_port, layout_to_constellation_chan, content_process_shutdown_chan, @@ -1158,7 +1154,6 @@ impl ScriptThread { layout_pair: layout_pair, pipeline_port: pipeline_port, constellation_chan: layout_to_constellation_chan, - panic_chan: panic_chan, paint_chan: paint_chan, script_chan: self.control_chan.clone(), image_cache_thread: self.image_cache_thread.clone(), @@ -1603,7 +1598,6 @@ impl ScriptThread { self.constellation_chan.clone(), self.control_chan.clone(), self.scheduler_chan.clone(), - self.panic_chan.clone(), ipc_timer_event_chan, incomplete.layout_chan, incomplete.pipeline_id, diff --git a/components/script_layout_interface/message.rs b/components/script_layout_interface/message.rs index ce97c805bb2..4fbed81429d 100644 --- a/components/script_layout_interface/message.rs +++ b/components/script_layout_interface/message.rs @@ -7,7 +7,7 @@ use euclid::point::Point2D; use euclid::rect::Rect; use gfx_traits::{Epoch, LayerId}; use ipc_channel::ipc::{IpcReceiver, IpcSender}; -use msg::constellation_msg::{PanicMsg, PipelineId}; +use msg::constellation_msg::PipelineId; use net_traits::image_cache_thread::ImageCacheThread; use profile_traits::mem::ReportsChan; use rpc::LayoutRPC; @@ -145,7 +145,6 @@ pub struct NewLayoutThreadInfo { pub layout_pair: (Sender<Msg>, Receiver<Msg>), pub pipeline_port: IpcReceiver<LayoutControlMsg>, pub constellation_chan: IpcSender<ConstellationMsg>, - pub panic_chan: IpcSender<PanicMsg>, pub script_chan: IpcSender<ConstellationControlMsg>, pub image_cache_thread: ImageCacheThread, pub paint_chan: OptionalOpaqueIpcSender, diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs index 175cc0b82f2..3b50d669b59 100644 --- a/components/script_traits/lib.rs +++ b/components/script_traits/lib.rs @@ -51,7 +51,7 @@ use ipc_channel::ipc::{IpcReceiver, IpcSender}; use layers::geometry::DevicePixel; use libc::c_void; use msg::constellation_msg::{FrameId, FrameType, Image, Key, KeyModifiers, KeyState, LoadData}; -use msg::constellation_msg::{NavigationDirection, PanicMsg, PipelineId, ReferrerPolicy}; +use msg::constellation_msg::{NavigationDirection, PipelineId, ReferrerPolicy}; use msg::constellation_msg::{PipelineNamespaceId, SubpageId, WindowSizeType}; use net_traits::bluetooth_thread::BluetoothMethodMsg; use net_traits::image_cache_thread::ImageCacheThread; @@ -142,8 +142,6 @@ pub struct NewLayoutInfo { pub paint_chan: OptionalOpaqueIpcSender, /// A port on which layout can receive messages from the pipeline. pub pipeline_port: IpcReceiver<LayoutControlMsg>, - /// A channel for sending panics on - pub panic_chan: IpcSender<PanicMsg>, /// A sender for the layout thread to communicate to the constellation. pub layout_to_constellation_chan: IpcSender<LayoutMsg>, /// A shutdown channel so that layout can tell the content process to shut down when it's done. @@ -394,8 +392,6 @@ pub struct InitialScriptState { pub control_port: IpcReceiver<ConstellationControlMsg>, /// A channel on which messages can be sent to the constellation from script. pub constellation_chan: IpcSender<ScriptMsg>, - /// A channel for sending panics to the constellation. - pub panic_chan: IpcSender<PanicMsg>, /// A channel to schedule timer events. pub scheduler_chan: IpcSender<TimerEventRequest>, /// A channel to the resource manager thread. @@ -471,8 +467,8 @@ pub enum MozBrowserEvent { /// handling `<menuitem>` element available within the browser `<iframe>`'s content. ContextMenu, /// Sent when an error occurred while trying to load content within a browser `<iframe>`. - /// Includes an optional human-readable description, and an optional machine-readable report. - Error(MozBrowserErrorType, Option<String>, Option<String>), + /// Includes a human-readable description, and a machine-readable report. + Error(MozBrowserErrorType, String, String), /// Sent when the favicon of a browser `<iframe>` changes. IconChange(String, String, String), /// Sent when the browser `<iframe>` has reached the server. @@ -656,8 +652,6 @@ pub struct WorkerGlobalScopeInit { pub constellation_chan: IpcSender<ScriptMsg>, /// Message to send to the scheduler pub scheduler_chan: IpcSender<TimerEventRequest>, - /// Sender which sends panic messages - pub panic_chan: IpcSender<PanicMsg>, /// The worker id pub worker_id: WorkerId, } diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock index d7eb68f237a..2134fd2d58a 100644 --- a/components/servo/Cargo.lock +++ b/components/servo/Cargo.lock @@ -2409,7 +2409,6 @@ name = "util" version = "0.0.1" dependencies = [ "app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/servo/main.rs b/components/servo/main.rs index 954c3f0e848..a13c2ca8b5d 100644 --- a/components/servo/main.rs +++ b/components/servo/main.rs @@ -26,7 +26,6 @@ extern crate backtrace; extern crate glutin_app as app; #[cfg(target_os = "android")] extern crate libc; -#[cfg(target_os = "android")] #[macro_use] extern crate log; // The Servo engine @@ -38,8 +37,8 @@ extern crate sig; use servo::Browser; use servo::compositing::windowing::WindowEvent; use servo::util::opts::{self, ArgumentParsingResult}; -use servo::util::panicking::initiate_panic_hook; use servo::util::servo_version; +use std::panic; use std::process; use std::rc::Rc; @@ -94,7 +93,20 @@ fn main() { None }; - initiate_panic_hook(); + // TODO: once log-panics is released, this can be replaced by + // log_panics::init(); + panic::set_hook(Box::new(|info| { + warn!("Panic hook called."); + let msg = match info.payload().downcast_ref::<&'static str>() { + Some(s) => *s, + None => match info.payload().downcast_ref::<String>() { + Some(s) => &**s, + None => "Box<Any>", + }, + }; + error!("{}", msg); + })); + setup_logging(); if let Some(token) = content_process_token { diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml index c713aac2957..e5f0bc9b5d3 100644 --- a/components/util/Cargo.toml +++ b/components/util/Cargo.toml @@ -11,12 +11,11 @@ path = "lib.rs" [features] # servo as opposed to geckolib -servo = ["serde", "serde_macros", "backtrace", "ipc-channel", "app_units/plugins", +servo = ["serde", "serde_macros", "ipc-channel", "app_units/plugins", "euclid/plugins", "euclid/unstable", "url/heap_size", "url/serde", "plugins"] [dependencies] app_units = "0.2.5" -backtrace = {version = "0.2.1", optional = true} bitflags = "0.7" euclid = "0.7.1" getopts = "0.2.11" diff --git a/components/util/lib.rs b/components/util/lib.rs index 6b906f83c8d..c36ec47a4cb 100644 --- a/components/util/lib.rs +++ b/components/util/lib.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #![cfg_attr(feature = "servo", feature(custom_derive))] -#![cfg_attr(feature = "servo", feature(fnbox))] #![cfg_attr(feature = "servo", feature(plugin))] #![cfg_attr(feature = "servo", feature(reflect_marker))] #![cfg_attr(feature = "servo", plugin(serde_macros))] @@ -12,7 +11,6 @@ #![deny(unsafe_code)] extern crate app_units; -#[cfg(feature = "servo")] extern crate backtrace; #[allow(unused_extern_crates)] #[macro_use] extern crate bitflags; extern crate euclid; extern crate getopts; @@ -31,7 +29,6 @@ pub mod basedir; pub mod geometry; #[cfg(feature = "servo")] #[allow(unsafe_code)] pub mod ipc; #[allow(unsafe_code)] pub mod opts; -#[cfg(feature = "servo")] pub mod panicking; pub mod prefs; pub mod resource_files; pub mod thread; diff --git a/components/util/panicking.rs b/components/util/panicking.rs deleted file mode 100644 index 20b3d002443..00000000000 --- a/components/util/panicking.rs +++ /dev/null @@ -1,52 +0,0 @@ -/* 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 http://mozilla.org/MPL/2.0/. */ - -use std::any::Any; -use std::boxed::FnBox; -use std::cell::RefCell; -use std::panic::{PanicInfo, take_hook, set_hook}; -use std::sync::{Once, ONCE_INIT}; -use std::thread; - -// only set the panic hook once -static HOOK_SET: Once = ONCE_INIT; - -/// TLS data pertaining to how failures should be reported -pub struct PanicHandlerLocal { - /// failure handler passed through spawn_named_with_send_on_failure - pub fail: Box<FnBox(&Any)> -} - -thread_local!(pub static LOCAL_INFO: RefCell<Option<PanicHandlerLocal>> = RefCell::new(None)); - -/// Set the thread-local panic hook -pub fn set_thread_local_hook(local: Box<FnBox(&Any)>) { - LOCAL_INFO.with(|i| *i.borrow_mut() = Some(PanicHandlerLocal { fail: local })); -} - -/// Initiates the custom panic hook -/// Should be called in main() after arguments have been parsed -pub fn initiate_panic_hook() { - // Set the panic handler only once. It is global. - HOOK_SET.call_once(|| { - // The original backtrace-printing hook. We still want to call this - let hook = take_hook(); - - let new_hook = move |info: &PanicInfo| { - let payload = info.payload(); - let name = thread::current().name().unwrap_or("<unknown thread>").to_string(); - // Notify error handlers stored in LOCAL_INFO if any - LOCAL_INFO.with(|i| { - if let Some(local_info) = i.borrow_mut().take() { - debug!("Thread `{}` failed, notifying error handlers", name); - (local_info.fail).call_box((payload, )); - } else { - hook(&info); - } - }); - }; - set_hook(Box::new(new_hook)); - }); - -} diff --git a/components/util/thread.rs b/components/util/thread.rs index 571d3529d9f..130187244db 100644 --- a/components/util/thread.rs +++ b/components/util/thread.rs @@ -2,12 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#[cfg(feature = "servo")] use backtrace::Backtrace; -#[cfg(feature = "servo")] use ipc_channel::ipc::IpcSender; -#[cfg(feature = "servo")] use panicking; -#[cfg(feature = "servo")] use serde::Serialize; -#[cfg(feature = "servo")] use std::any::Any; -#[cfg(feature = "servo")] use thread_state; use std::thread; pub fn spawn_named<F>(name: String, f: F) @@ -15,39 +9,3 @@ pub fn spawn_named<F>(name: String, f: F) { thread::Builder::new().name(name).spawn(f).expect("Thread spawn failed"); } - -/// Arrange to send a particular message to a channel if the thread fails. -#[cfg(feature = "servo")] -pub fn spawn_named_with_send_on_panic<F, Id>(name: String, - state: thread_state::ThreadState, - f: F, - id: Id, - panic_chan: IpcSender<(Id, String, String)>) - where F: FnOnce() + Send + 'static, - Id: Copy + Send + Serialize + 'static, -{ - thread::Builder::new().name(name).spawn(move || { - thread_state::initialize(state); - panicking::set_thread_local_hook(Box::new(move |payload: &Any| { - debug!("Thread failed, notifying constellation"); - let reason = payload.downcast_ref::<String>().map(|s| String::from(&**s)) - .or(payload.downcast_ref::<&'static str>().map(|s| String::from(*s))) - .unwrap_or_else(|| String::from("<unknown reason>")); - // FIXME(ajeffrey): Really we should send the backtrace itself, - // not just a string representation. Unfortunately we can't, because - // Servo won't compile backtrace with the serialize-serde feature: - // - // .../quasi_macros-0.9.0/src/lib.rs:19:29: 19:32 error: mismatched types: - // expected `&mut syntex::Registry`, - // found `&mut rustc_plugin::Registry<'_>` - // (expected struct `syntex::Registry`, - // found struct `rustc_plugin::Registry`) [E0308] - // .../quasi_macros-0.9.0/src/lib.rs:19 quasi_codegen::register(reg); - // - // so for the moment we just send a debug string. - let backtrace = format!("{:?}", Backtrace::new()); - let _ = panic_chan.send((id, reason, backtrace)); - })); - f() - }).expect("Thread spawn failed"); -} diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock index 591371cbfc0..558e8deab15 100644 --- a/ports/cef/Cargo.lock +++ b/ports/cef/Cargo.lock @@ -2278,7 +2278,6 @@ name = "util" version = "0.0.1" dependencies = [ "app_units 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini b/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini index ffcf84dd35c..b7e66c83a20 100644 --- a/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini +++ b/tests/wpt/metadata/FileAPI/blob/Blob-XHR-revoke.html.ini @@ -1,7 +1,5 @@ [Blob-XHR-revoke.html] type: testharness - expected: TIMEOUT - [Revoking blob URL used with XMLHttpRequest] - expected: TIMEOUT - bug: https://github.com/servo/servo/issues/10539 + expected: CRASH + bug: https://github.com/servo/servo/issues/10539 |