Renderer crash and curious SkCanvas __vfptr

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

Renderer crash and curious SkCanvas __vfptr

Postby ndesktop » Wed Dec 06, 2023 9:13 am

I em encountering a crash in libcef branch 5845, version 116.0.5845.97, with a number of 20+ Chromium patches and many other CEF changes.
The Windows 10 x64 callstack looks like this:
Code: Select all
    [Inline Frame] libcef.dll!SkColorFilter::filterColor4f(const SkRGBA4f<3> & origSrcColor, SkColorSpace * srcCS, SkColorSpace * dstCS) Line 53   C++
    libcef.dll!SkColorFilter::filterColor(unsigned int c) Line 44   C++
>   [Inline Frame] libcef.dll!SkColorFilterBase::affectsTransparentBlack() Line 77   C++
    [Inline Frame] libcef.dll!must_cover_prior_device(const SkImageFilter * backdrop, const SkPaint & restorePaint) Line 1000   C++
    libcef.dll!SkCanvas::internalSaveLayer(const SkCanvas::SaveLayerRec & rec, SkCanvas::SaveLayerStrategy strategy) Line 1055   C++
    libcef.dll!SkCanvas::saveLayer(const SkCanvas::SaveLayerRec & rec) Line 624   C++
    libcef.dll!SkCanvas::saveLayer(const SkRect * bounds, const SkPaint * paint) Line 610   C++
    [Inline Frame] libcef.dll!cc::SaveLayerOp::RasterWithFlags(const cc::SaveLayerOp * op, const cc::PaintFlags * flags, SkCanvas * canvas, const cc::PlaybackParams & params) Line 1450   C++
    [Inline Frame] libcef.dll!cc::`anonymous namespace'::Rasterizer<cc::SaveLayerOp,1>::RasterWithFlags(const cc::SaveLayerOp * op, const cc::PaintFlags * flags, SkCanvas * canvas, const cc::PlaybackParams & params) Line 185   C++
    [Inline Frame] libcef.dll!cc::`anonymous namespace'::<lambda_115>::operator()(const cc::PaintOp * op, const cc::PaintFlags * flags, SkCanvas * canvas, const cc::PlaybackParams & params) Line 220   C++
    libcef.dll!cc::`anonymous namespace'::<lambda_115>::__invoke(const cc::PaintOp * op, const cc::PaintFlags * flags, SkCanvas * canvas, const cc::PlaybackParams & params) Line 220   C++
    libcef.dll!cc::PaintOpBuffer::Playback(SkCanvas * canvas, const cc::PlaybackParams & params, const std::__Cr::vector<unsigned long long,std::__Cr::allocator<unsigned long long>> * offsets) Line 247   C++
    libcef.dll!cc::PaintOpBuffer::Playback(SkCanvas * canvas, const cc::PlaybackParams & params, const std::__Cr::vector<unsigned long long,std::__Cr::allocator<unsigned long long>> * offsets) Line 252   C++
    libcef.dll!cc::PaintOpBuffer::Playback(SkCanvas * canvas, const cc::PlaybackParams & params, const std::__Cr::vector<unsigned long long,std::__Cr::allocator<unsigned long long>> * offsets) Line 252   C++
    libcef.dll!cc::PaintOpBuffer::Playback(SkCanvas * canvas, const cc::PlaybackParams & params, const std::__Cr::vector<unsigned long long,std::__Cr::allocator<unsigned long long>> * offsets) Line 252   C++
    libcef.dll!cc::DisplayItemList::Raster(SkCanvas * canvas, cc::ImageProvider * image_provider) Line 91   C++
    libcef.dll!cc::RasterSource::PlaybackDisplayListToCanvas(SkCanvas * raster_canvas, cc::ImageProvider * image_provider) Line 126   C++
    libcef.dll!cc::RasterSource::PlaybackToCanvas(SkCanvas * raster_canvas, const gfx::Size & content_size, const gfx::Rect & canvas_bitmap_rect, const gfx::Rect & canvas_playback_rect, const gfx::AxisTransform2d & raster_transform, const cc::RasterSource::PlaybackSettings & settings) Line 117   C++
    libcef.dll!cc::RasterBufferProvider::PlaybackToMemory(void * memory, viz::SharedImageFormat format, const gfx::Size & size, unsigned __int64 stride, const cc::RasterSource * raster_source, const gfx::Rect & canvas_bitmap_rect, const gfx::Rect & canvas_playback_rect, const gfx::AxisTransform2d & transform, const gfx::ColorSpace & target_color_space, bool gpu_compositing, const cc::RasterSource::PlaybackSettings & playback_settings) Line 95   C++
    libcef.dll!cc::`anonymous namespace'::BitmapRasterBufferImpl::Playback(const cc::RasterSource * raster_source, const gfx::Rect & raster_full_rect, const gfx::Rect & raster_dirty_rect, unsigned __int64 new_content_id, const gfx::AxisTransform2d & transform, const cc::RasterSource::PlaybackSettings & playback_settings, const GURL & url) Line 104   C++
    libcef.dll!cc::`anonymous namespace'::RasterTaskImpl::RunOnWorkerThread() Line 142   C++
    libcef.dll!cc::CategorizedWorkerPoolJob::Run(base::span<const cc::TaskCategory,18446744073709551615> categories, base::JobDelegate * job_delegate) Line 553   C++
    [Inline Frame] libcef.dll!base::internal::FunctorTraits<void (cc::CategorizedWorkerPoolJob::*)(base::span<const cc::TaskCategory,18446744073709551615>, base::JobDelegate *),void>::Invoke(void(cc::CategorizedWorkerPoolJob::*)(base::span<const cc::TaskCategory,18446744073709551615>, base::JobDelegate *) method, cc::CategorizedWorkerPoolJob * && receiver_ptr, const base::span<const cc::TaskCategory,18446744073709551615> & args, base::JobDelegate * && args) Line 746   C++
    [Inline Frame] libcef.dll!base::internal::InvokeHelper<0,void,0,1>::MakeItSo(void(cc::CategorizedWorkerPoolJob::*)(base::span<const cc::TaskCategory,18446744073709551615>, base::JobDelegate *) & functor, const std::__Cr::tuple<base::internal::UnretainedWrapper<cc::CategorizedWorkerPoolJob,base::unretained_traits::MayNotDangle,0>,base::span<const cc::TaskCategory,18446744073709551615>> & bound, base::JobDelegate * && args) Line 925   C++
    [Inline Frame] libcef.dll!base::internal::Invoker<base::internal::BindState<void (cc::CategorizedWorkerPoolJob::*)(base::span<const cc::TaskCategory,18446744073709551615>, base::JobDelegate *),base::internal::UnretainedWrapper<cc::CategorizedWorkerPoolJob,base::unretained_traits::MayNotDangle,0>,base::span<const cc::TaskCategory,18446744073709551615>>,void (base::JobDelegate *)>::RunImpl(void(cc::CategorizedWorkerPoolJob::*)(base::span<const cc::TaskCategory,18446744073709551615>, base::JobDelegate *) & functor, const std::__Cr::tuple<base::internal::UnretainedWrapper<cc::CategorizedWorkerPoolJob,base::unretained_traits::MayNotDangle,0>,base::span<const cc::TaskCategory,18446744073709551615>> & bound, std::__Cr::integer_sequence<unsigned long long,0,1> seq, base::JobDelegate * && unbound_args) Line 1025   C++
    libcef.dll!base::internal::Invoker<base::internal::BindState<void (cc::CategorizedWorkerPoolJob::*)(base::span<const cc::TaskCategory,18446744073709551615>, base::JobDelegate *),base::internal::UnretainedWrapper<cc::CategorizedWorkerPoolJob,base::unretained_traits::MayNotDangle,0>,base::span<const cc::TaskCategory,18446744073709551615>>,void (base::JobDelegate *)>::Run(base::internal::BindStateBase * base, base::JobDelegate * unbound_args) Line 989   C++
    [Inline Frame] libcef.dll!base::RepeatingCallback<void (base::JobDelegate *)>::Run(base::JobDelegate * args) Line 333   C++
    [Inline Frame] libcef.dll!base::internal::JobTaskSource::JobTaskSource::<lambda_0>::operator()(base::internal::JobTaskSource * self) Line 104   C++
    [Inline Frame] libcef.dll!base::internal::FunctorTraits<`lambda at ..\..\base\task\thread_pool\job_task_source.cc:100:11',void>::Invoke(const base::internal::JobTaskSource::JobTaskSource::<lambda_0> & functor, base::internal::JobTaskSource * && args) Line 621   C++
    [Inline Frame] libcef.dll!base::internal::InvokeHelper<0,void,0>::MakeItSo(const base::internal::JobTaskSource::JobTaskSource::<lambda_0> & functor, const std::__Cr::tuple<base::internal::UnretainedWrapper<base::internal::JobTaskSource,base::unretained_traits::MayNotDangle,0>> & bound) Line 925   C++
    [Inline Frame] libcef.dll!base::internal::Invoker<base::internal::BindState<`lambda at ..\..\base\task\thread_pool\job_task_source.cc:100:11',base::internal::UnretainedWrapper<base::internal::JobTaskSource,base::unretained_traits::MayNotDangle,0>>,void ()>::RunImpl(const base::internal::JobTaskSource::JobTaskSource::<lambda_0> & functor, const std::__Cr::tuple<base::internal::UnretainedWrapper<base::internal::JobTaskSource,base::unretained_traits::MayNotDangle,0>> & bound, std::__Cr::integer_sequence<unsigned long long,0> seq) Line 1025   C++
    libcef.dll!base::internal::Invoker<base::internal::BindState<`lambda at ..\..\base\task\thread_pool\job_task_source.cc:100:11',base::internal::UnretainedWrapper<base::internal::JobTaskSource,base::unretained_traits::MayNotDangle,0>>,void ()>::Run(base::internal::BindStateBase * base) Line 989   C++
    [Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 152   C++
    libcef.dll!base::TaskAnnotator::RunTaskImpl(base::PendingTask & pending_task) Line 186   C++
    [Inline Frame] libcef.dll!base::TaskAnnotator::RunTask(perfetto::StaticString event_name, base::PendingTask & pending_task, base::internal::TaskTracker::RunTaskImpl::<lambda_0> && args) Line 88   C++
    [Inline Frame] libcef.dll!base::internal::TaskTracker::RunTaskImpl(base::internal::Task & task, const base::TaskTraits & traits, base::internal::TaskSource * task_source, const base::SequenceToken & token) Line 643   C++
    libcef.dll!base::internal::TaskTracker::RunSkipOnShutdown(base::internal::Task & task, const base::TaskTraits & traits, base::internal::TaskSource * task_source, const base::SequenceToken & token) Line 628   C++
    [Inline Frame] libcef.dll!base::internal::TaskTracker::RunTaskWithShutdownBehavior(base::internal::Task & task, const base::TaskTraits & traits, base::internal::TaskSource * task_source, const base::SequenceToken & token) Line 658   C++
    [Inline Frame] libcef.dll!base::internal::TaskTracker::RunTask(base::internal::Task task, base::internal::TaskSource * task_source, const base::TaskTraits & traits) Line 485   C++
    libcef.dll!base::internal::TaskTracker::RunAndPopNextTask(base::internal::RegisteredTaskSource task_source) Line 400   C++
    libcef.dll!base::internal::WorkerThread::RunWorker() Line 480   C++
    libcef.dll!base::internal::WorkerThread::RunPooledWorker() Line 356   C++
    libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 126   C++
    [External Code]   


On the last function call, SkColorFilter::filterColor4f, this looks invalid: this = 0x0000410c0263d800 VS crash dump display:
Code: Select all
this   0x0000410c0263d800 {...}   SkColorFilter *
  SkFlattenable   {...}   SkFlattenable
    SkRefCnt   {...}   SkRefCnt
      SkRefCntBase   {fRefCnt={...} }   SkRefCntBase
        __vfptr   0x0000000000000000 {???, ???}   void * *
        fRefCnt   {...}   std::__Cr::atomic<int>
          std::__Cr::__atomic_base<int,1>   {...}   std::__Cr::__atomic_base<int,1>
            std::__Cr::__atomic_base<int,0>   {__a_={...} }   std::__Cr::__atomic_base<int,0>
              __a_   {...}   std::__Cr::__cxx_atomic_impl<int,std::__Cr::__cxx_atomic_base_impl<int>>
                std::__Cr::__cxx_atomic_base_impl<int>   {__a_value=??? }   std::__Cr::__cxx_atomic_base_impl<int>
        __a_value   <Unable to read memory>   


But two functions upper, in SkColorFilterBase::affectsTransparentBlack(), the *this* display looks like this:
Code: Select all
this   0x0000410c00b38000 {fMCRecStorage=0x0000410c00b38008 {0, 0, 71519807176752, 71519807177808, 71519807179784, ...} ...}   SkCanvas *
   __vfptr   0x00007ffcb8f82e80 {libcef.dll!const SkCanvas::`vftable'} {0x00007ffcb2cf43d0 {libcef.dll!SkCanvas::~SkCanvas(void)}, ...}   void * *
      [0]   0x00007ffcb2cf43d0 {libcef.dll!SkCanvas::~SkCanvas(void)}   void *
      [1]   0x00007ffcb0e280a0 {libcef.dll!SkCanvas::getBaseLayerSize(void)}   void *
      [2]   0x00007ffcb3181070 {libcef.dll!SkCanvas::recordingContext(void)}   void *
      [3]   0x00007ffcb3967a40 {libcef.dll!SkCanvas::recorder(void)}   void *
      [4]   0x00007ffcb2fb60a0 {libcef.dll!SkCanvas::isClipEmpty(void)}   void *
      [5]   0x00007ffcb0e280c0 {libcef.dll!SkCanvas::isClipRect(void)}   void *
      [6]   0x00007ffcb39672c0 {libcef.dll!SkCanvas::onNewSurface(const SkImageInfo &, const SkSurfaceProps &)}   void *
      [7]   0x00007ffcb39673b0 {libcef.dll!SkCanvas::onPeekPixels(SkPixmap *)}   void *
      [8]   0x00007ffcb39674d0 {libcef.dll!SkCanvas::onAccessTopLayerPixels(SkPixmap *)}   void *
      [9]   0x00007ffcaf3a5490 {libcef.dll!SkCanvas::onImageInfo(void)}   void *
      [10]   0x00007ffcaf142ca0 {libcef.dll!SkCanvas::onGetProps(SkSurfaceProps *, bool)}   void *
      [11]   0x00007ffcb3966910 {libcef.dll!SkCanvas::onFlush(void)}   void *
      [12]   0x00007ffcaec51d80 {libcef.dll!shutdown_checker::AssertNotShutdown(void)}   void *
      [13]   0x00007ffcaed3bd70 {libcef.dll!CefCToCppRefCounted<CefBaseRefCountedCToCpp,CefBaseRefCounted,_cef_base_ref_counted_t>::UnwrapDerived(CefWrapperType, CefBaseRefCounted *)}   void *
      [14]   0x00007ffcb33de490 {libcef.dll!mojo::core::Dispatcher::BeginTransit(void)}   void *
      [15]   0x00007ffcaec51d80 {libcef.dll!shutdown_checker::AssertNotShutdown(void)}   void *
      [16]   0x00007ffcaec51d80 {libcef.dll!shutdown_checker::AssertNotShutdown(void)}   void *
      [17]   0x00007ffcb33f01a0 {libcef.dll!content::WebContentsObserver::UserAgentOverrideSet(const blink::UserAgentOverride &)}   void *
      [18]   0x00007ffcaec51d80 {libcef.dll!shutdown_checker::AssertNotShutdown(void)}   void *
      [19]   0x00007ffcaec51d80 {libcef.dll!shutdown_checker::AssertNotShutdown(void)}   void *
      [20]   0x00007ffcaec51d80 {libcef.dll!shutdown_checker::AssertNotShutdown(void)}   void *
      [21]   0x00007ffcaf1b6ab0 {libcef.dll!SkCanvas::onDrawPaint(const SkPaint &)}   void *
      [22]   0x00007ffcb3969220 {libcef.dll!SkCanvas::onDrawBehind(const SkPaint &)}   void *
      [23]   0x00007ffcb2e6bde0 {libcef.dll!SkCanvas::onDrawRect(const SkRect &, const SkPaint &)}   void *
...

*this* is SkColorFilterBase; affectsTransparentBlack calls into the base class of SkColorFilterBase, which is SkColorFilter.
But the layout looks like a SkCanvas; even more, looking into src/third_party/skia/include/core/SkCanvas.h, the virtual functions are, in order
SkCanvas, getBaseLayerSize ... onGetProps, correct until index 10.
But starting from index 12 to 20 (including) there are, in order
Code: Select all
[11] SkCanvas::onFlush
[12]   shutdown_checker::AssertNotShutdown(void)
[13]   CefCToCppRefCounted<CefBaseRefCountedCToCpp,CefBaseRefCounted,_cef_base_ref_counted_t>::UnwrapDerived(CefWrapperType, CefBaseRefCounted *)
[14]   mojo::core::Dispatcher::BeginTransit(void)
[15]   shutdown_checker::AssertNotShutdown(void)
[16]   shutdown_checker::AssertNotShutdown(void)
[17]   content::WebContentsObserver::UserAgentOverrideSet(const blink::UserAgentOverride &)
[18]   shutdown_checker::AssertNotShutdown(void)
[19]   shutdown_checker::AssertNotShutdown(void)
[20]   shutdown_checker::AssertNotShutdown(void)
[21]   SkCanvas::onDrawPaint(const SkPaint &)

for a number of 9 functions between onFlush and onDrawPaint, while in SkCanvas after onGetProps, are the following virtual functions:
Code: Select all
...
virtual void onFlush();
virtual void willSave() {}
virtual bool onDoSaveBehind(const SkRect*) { return true; }
virtual void willRestore() {}
virtual void didRestore() {}
virtual void didConcat44(const SkM44&) {}
virtual void didSetM44(const SkM44&) {}
virtual void didTranslate(SkScalar, SkScalar) {}
virtual void didScale(SkScalar, SkScalar) {}
virtual void onDrawPaint(const SkPaint& paint);
virtual void onDrawBehind(const SkPaint& paint);

So between onFlush and onDrawPaint, there are 8 functions (willSave - onDoSaveBehind - ... - didScale), while the upper layout between SkCanvas::onFlush and SkCanvas::onDrawPaint there are 9 functions.

Maybe I'm not reading the __vfptr layout correctly, but did someone else noticed a crash similar with this one?
ndesktop
Master
 
Posts: 756
Joined: Thu Dec 03, 2015 10:10 am

Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 194 guests