WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
190092
CRASH in CVPixelBufferGetBytePointerCallback()
https://bugs.webkit.org/show_bug.cgi?id=190092
Summary
CRASH in CVPixelBufferGetBytePointerCallback()
Jer Noble
Reported
2018-09-28 14:32:29 PDT
CRASH in CVPixelBufferGetBytePointerCallback()
Attachments
Patch
(6.61 KB, patch)
2018-09-28 14:36 PDT
,
Jer Noble
no flags
Details
Formatted Diff
Diff
Patch
(6.58 KB, patch)
2018-09-28 14:53 PDT
,
Jer Noble
no flags
Details
Formatted Diff
Diff
Patch
(6.83 KB, patch)
2018-09-28 16:35 PDT
,
Jer Noble
no flags
Details
Formatted Diff
Diff
Patch
(6.81 KB, patch)
2018-10-01 10:40 PDT
,
Jer Noble
no flags
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Jer Noble
Comment 1
2018-09-28 14:32:57 PDT
<
rdar://43824620
>
Radar WebKit Bug Importer
Comment 2
2018-09-28 14:33:33 PDT
<
rdar://problem/44875084
>
Jer Noble
Comment 3
2018-09-28 14:36:11 PDT
Created
attachment 351114
[details]
Patch
Eric Carlson
Comment 4
2018-09-28 14:41:00 PDT
Comment on
attachment 351114
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351114&action=review
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:108 > + --info->lockCount;
Might be worth adding something like "ASSERT(info->lockCount > 0)"
Tim Horton
Comment 5
2018-09-28 14:47:10 PDT
Comment on
attachment 351114
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351114&action=review
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:128 > + CVReturn result = CVPixelBufferLockBaseAddress(info->pixelBuffer.get(), kCVPixelBufferLock_ReadOnly);
I think you want an unlock here.
Jer Noble
Comment 6
2018-09-28 14:53:23 PDT
Created
attachment 351115
[details]
Patch Removed the Lock from the info struct, fixed the incorrect lock in the release info callback, and added release logging of the CVPixelBuffer size in the get byte pointer callback.
Jer Noble
Comment 7
2018-09-28 14:54:07 PDT
<
rdar://problem/43824620
>
Jer Noble
Comment 8
2018-09-28 15:06:58 PDT
Comment on
attachment 351114
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351114&action=review
>> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:108 >> + --info->lockCount; > > Might be worth adding something like "ASSERT(info->lockCount > 0)"
Good idea.
Jer Noble
Comment 9
2018-09-28 16:35:17 PDT
Created
attachment 351138
[details]
Patch
Said Abou-Hallawa
Comment 10
2018-10-01 10:18:04 PDT
Comment on
attachment 351138
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=351138&action=review
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:61 > + int lockCount { 0 };
Since you changed the pointer type to be RetainPtr<>, can't we get rid of lockCount and use CFRetain(pixelBuffer.get()) CFRelease(pixelBuffer.get()) CFGetRetainCount(pixelBuffer.get()) Instead of: ++info->lockCount --info->lockCount info->lockCount I think it is conceptually correct as well. You can consider the lock count as a ref/retain count.
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:83 > + ++info->lockCount;
Is this code thread-safe?
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:85 > + RELEASE_LOG_INFO(Media, "CVPixelBufferGetBytePointerCallback() returning bytePointer: %p, size: %zu", address, CVPixelBufferGetDataSize(info->pixelBuffer.get()));
How often does this function get called? If it's called many times, I would suggest removing this particular RELEASE_LOG_INFO statement because it might add tons of unneeded information.
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:139 > + info->pixelBuffer = nullptr; > + delete info;
If you change info to std::unique_ptr or you pass RetainPtr<CVPixelBufferRef>, you will not have to do any of these releases. The pointer will be delete itself once the caller of CVPixelBufferReleaseInfoCallback() releases the last reference to this pointer.
> Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:180 > + CVPixelBufferInfo* info = new CVPixelBufferInfo();
We usually do not do bare "new" calls. Can't we do it this way? CVPixelBufferInfo* info = std::make_unique<CVPixelBufferInfo>().release(); Or can't we make info a std::unique_ptr? auto info = std::make_unique<CVPixelBufferInfo>(); Or can't we pass the RetainPtr itself instead of the "info" pointer and use CFRetain/CFRelease instead of lockCount? RetainPtr<CVPixelBufferRef> pixelBuffer = WTFMove(buffer);
Jer Noble
Comment 11
2018-10-01 10:28:53 PDT
(In reply to Said Abou-Hallawa from
comment #10
)
> Comment on
attachment 351138
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=351138&action=review
> > > Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:61 > > + int lockCount { 0 }; > > Since you changed the pointer type to be RetainPtr<>, can't we get rid of > lockCount and use > > CFRetain(pixelBuffer.get()) > CFRelease(pixelBuffer.get()) > CFGetRetainCount(pixelBuffer.get()) > > Instead of: > ++info->lockCount > --info->lockCount > info->lockCount
No, because that would turn a logging change into a behavior change. We don't want to map locking the pixel buffer onto ref'ing the buffer itself, especially if the client isn't matching up its locks and unlocks.
> I think it is conceptually correct as well. You can consider the lock count > as a ref/retain count.
No, you absolutely cannot. The lock count is on the CVPixelBuffer's internal storage, not the CVPixelBuffer itself. Their lifetimes are not the same, and we can't treat them as the same.
> > Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:83 > > + ++info->lockCount; > > Is this code thread-safe?
Nope! But again, this is just a logging change. If the caller is calling lock and unlock simultaneously on different threads, there's already huge problems because the pointer returned by lock() won't be valid after unlock() is called.+
> > Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:85 > > + RELEASE_LOG_INFO(Media, "CVPixelBufferGetBytePointerCallback() returning bytePointer: %p, size: %zu", address, CVPixelBufferGetDataSize(info->pixelBuffer.get())); > > How often does this function get called? If it's called many times, I would > suggest removing this particular RELEASE_LOG_INFO statement because it might > add tons of unneeded information.
According to my testing, this is called twice per enter- or exit-fullscreen operation, which is not very often. The entire purpose of this logging is to allow us to co-relate the crash location to what CV thinks the size of the buffer is, so I think this is particularly essential logging.
> > Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:139 > > + info->pixelBuffer = nullptr; > > + delete info; > > If you change info to std::unique_ptr or you pass > RetainPtr<CVPixelBufferRef>, you will not have to do any of these releases. > The pointer will be delete itself once the caller of > CVPixelBufferReleaseInfoCallback() releases the last reference to this > pointer.
Not sure I really understand your point here. The CVPixelBuffer is stored in a RetainPtr. And info can't be stored in a std::unique_ptr, since it's just passed around as a void*.
> > Source/WebCore/platform/graphics/cv/PixelBufferConformerCV.cpp:180 > > + CVPixelBufferInfo* info = new CVPixelBufferInfo(); > > We usually do not do bare "new" calls. > > Can't we do it this way? > CVPixelBufferInfo* info = > std::make_unique<CVPixelBufferInfo>().release();
How does that solve anything? That's just a complicated wrapper around 'new'.
> Or can't we make info a std::unique_ptr? > auto info = std::make_unique<CVPixelBufferInfo>(); > > Or can't we pass the RetainPtr itself instead of the "info" pointer and use > CFRetain/CFRelease instead of lockCount? > RetainPtr<CVPixelBufferRef> pixelBuffer = WTFMove(buffer);
No. Using a NSObject* instead of a C++ object is just kicking the can down the road. It doesn't solve anything on its own. This data structure still needs to be passed around as a void* and cast to a type.
Jer Noble
Comment 12
2018-10-01 10:40:23 PDT
Created
attachment 351263
[details]
Patch One more fix for the bots.
WebKit Commit Bot
Comment 13
2018-10-03 12:28:39 PDT
Comment on
attachment 351263
[details]
Patch Clearing flags on attachment: 351263 Committed
r236806
: <
https://trac.webkit.org/changeset/236806
>
WebKit Commit Bot
Comment 14
2018-10-03 12:28:41 PDT
All reviewed patches have been landed. Closing bug.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug