| Index: content/browser/indexed_db/indexed_db_backing_store.cc | 
| diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc | 
| index e09458913785c85a1b5e963db68819147f48c3a4..13b01cca70dfa6dde19f1ebcc9bcecddd824cfad 100644 | 
| --- a/content/browser/indexed_db/indexed_db_backing_store.cc | 
| +++ b/content/browser/indexed_db/indexed_db_backing_store.cc | 
| @@ -4066,8 +4066,10 @@ IndexedDBBackingStore::OpenIndexCursor( | 
|  | 
| IndexedDBBackingStore::Transaction::Transaction( | 
| IndexedDBBackingStore* backing_store) | 
| -    : backing_store_(backing_store), database_id_(-1), committing_(false) { | 
| -} | 
| +    : backing_store_(backing_store), | 
| +      database_id_(-1), | 
| +      committing_(false), | 
| +      ptr_factory_(this) {} | 
|  | 
| IndexedDBBackingStore::Transaction::~Transaction() { | 
| DCHECK(!committing_); | 
| @@ -4341,22 +4343,27 @@ leveldb::Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() { | 
| class IndexedDBBackingStore::Transaction::BlobWriteCallbackWrapper | 
| : public IndexedDBBackingStore::BlobWriteCallback { | 
| public: | 
| -  BlobWriteCallbackWrapper(IndexedDBBackingStore::Transaction* transaction, | 
| -                           scoped_refptr<BlobWriteCallback> callback) | 
| -      : transaction_(transaction), callback_(callback) {} | 
| +  BlobWriteCallbackWrapper( | 
| +      base::WeakPtr<IndexedDBBackingStore::Transaction> transaction, | 
| +      void* tracing_end_ptr, | 
| +      scoped_refptr<BlobWriteCallback> callback) | 
| +      : transaction_(std::move(transaction)), | 
| +        tracing_end_ptr_(tracing_end_ptr), | 
| +        callback_(callback) {} | 
| void Run(bool succeeded) override { | 
| IDB_ASYNC_TRACE_END("IndexedDBBackingStore::Transaction::WriteNewBlobs", | 
| -                        transaction_); | 
| +                        tracing_end_ptr_); | 
| callback_->Run(succeeded); | 
| -    if (succeeded)  // Else it's already been deleted during rollback. | 
| -      transaction_->chained_blob_writer_ = NULL; | 
| +    if (transaction_ && succeeded) | 
| +      transaction_->chained_blob_writer_ = nullptr; | 
| } | 
|  | 
| private: | 
| ~BlobWriteCallbackWrapper() override {} | 
| friend class base::RefCounted<IndexedDBBackingStore::BlobWriteCallback>; | 
|  | 
| -  IndexedDBBackingStore::Transaction* transaction_; | 
| +  base::WeakPtr<IndexedDBBackingStore::Transaction> transaction_; | 
| +  const void* const tracing_end_ptr_; | 
| scoped_refptr<BlobWriteCallback> callback_; | 
|  | 
| DISALLOW_COPY_AND_ASSIGN(BlobWriteCallbackWrapper); | 
| @@ -4379,12 +4386,11 @@ void IndexedDBBackingStore::Transaction::WriteNewBlobs( | 
| transaction_->Put(blob_entry_iter.first.Encode(), | 
| &blob_entry_iter.second); | 
| } | 
| -  // Creating the writer will start it going asynchronously. | 
| -  chained_blob_writer_ = | 
| -      new ChainedBlobWriterImpl(database_id_, | 
| -                                backing_store_, | 
| -                                new_files_to_write, | 
| -                                new BlobWriteCallbackWrapper(this, callback)); | 
| +  // Creating the writer will start it going asynchronously. The transaction | 
| +  // can be destructed before the callback is triggered. | 
| +  chained_blob_writer_ = new ChainedBlobWriterImpl( | 
| +      database_id_, backing_store_, new_files_to_write, | 
| +      new BlobWriteCallbackWrapper(ptr_factory_.GetWeakPtr(), this, callback)); | 
| } | 
|  | 
| void IndexedDBBackingStore::Transaction::Rollback() { | 
| @@ -4399,7 +4405,7 @@ void IndexedDBBackingStore::Transaction::Rollback() { | 
| chained_blob_writer_->Abort(); | 
| chained_blob_writer_ = NULL; | 
| } | 
| -  if (transaction_.get() == NULL) | 
| +  if (!transaction_) | 
| return; | 
| transaction_->Rollback(); | 
| transaction_ = NULL; | 
|  |