Problem with ScopeInfo when used codeCache

48 views
Skip to first unread message

alex...@gmail.com

unread,
Apr 9, 2025, 4:14:53 AMApr 9
to v8-users
Hey folks,

I have a class with many private functions/properties (77 in the most recent incarnation). When I get a stack trace (say to create an Error object) when I'm inside a function in this class, we end up in ClassScope::ClassScope in scopes.cc:
```
  if (scope_info->HasSavedClassVariable()) {
    Tagged<String> name;
    int index;
    std::tie(name, index) = scope_info->SavedClassVariable();
```

This ends up loading an index tacked on to the end of the context slots in the ScopeInfo heap object which looks like:

```
0x25eabdda3541: [ScopeInfo]
- map: 0x2ad145840d71 <Map(SCOPE_INFO_TYPE)>
- parameters: 0
- context locals : 79
- local names in a hashtable: 0x25eabdda2d19 <Other heap object (NAME_TO_INDEX_HASH_TABLE_TYPE)>
- scope type: CLASS_SCOPE
- language mode: strict
- class scope has private brand
- has saved class variable
- function kind: NormalFunction
- outer scope info: 0x25eabdda2801 <ScopeInfo MODULE_SCOPE>
- start position: 22541
- end position: 282321
- length: 87
- context slots {
- 51: 0x1a45b21b8311 <String[17]: ##getTransactionId>
- 72: 0x1a45b21b7fc9 <String[13]: ##valueMatches>
- 0: 0x1a45b21b6d21 <String[17]: ##allowRunJsScript>
- 32: 0x1a45b21b71d1 <String[5]: ##call>
- 75: 0x1a45b21b9e59 <String[17]: ##writeNumericParm>
- 77: 0x2ad145846ae1 <String[6]: #.brand>
- 59: 0x1070007a8419 <String[13]: ##sendResponse>
- 29: 0x1a45b21b70a1 <String[9]: ##timeZone>
- 37: 0x1a45b21b84a9 <String[11]: ##createFind>
- 71: 0x1a45b21bcc91 <String[14]: ##updateRecords>
- 17: 0x1a45b21b6f69 <String[19]: ##pendingImageFields>
- 28: 0x1a45b21b7081 <String[14]: ##syncSemaphore>
- 27: 0x1a45b21b7061 <String[14]: ##syncQueueLock>
- 39: 0x1a45b21b8a31 <String[5]: ##find>
- 45: 0x1a45b21b91c1 <String[25]: ##getFindRecordTypeInfoSet>
- 8: 0x1a45b21b6df9 <String[9]: ##inBuffer>
- 44: 0x1a45b21b9d91 <String[12]: ##getFileInfo>
- 66: 0x1a45b21bd609 <String[16]: ##syncBuildRecord>
- 78: 0x208cca45af99 <String[10]: #Connection>
```
A lot more slots follow, but after them is the class variable info retrieved by the TorqueGeneratedScopeInfo::saved_class_variable_info function. FWIW, job in lldb does not show the value (23 in my example).

That saved_class_variable_info is then used to index a name and value in the local names hash table referenced by the ScopeInfo heap object. And this table is used in ScopeInfo::SavedClassVariable to get the class name and index:
```
  if (HasInlinedLocalNames()) {
    ...
  } else {
    // The saved class variable info corresponds to the offset in the hash
    // table storage.
    InternalIndex entry(saved_class_variable_info());
    Tagged<NameToIndexHashTable> table = context_local_names_hashtable();
    Tagged<Object> name = table->KeyAt(entry);
    DCHECK(IsString(name));
    return std::make_pair(Cast<String>(name), table->IndexAt(entry));
  } 
```
The table is a hash table because it's gotten beyond a certain size. In my example it looks like:
```
0x25eabdda2d19: [NameToIndexHashTable]
- FixedArray length: 259
  - elements: 79
  - deleted: 0
  - capacity: 12
  - elements: {
              0: #getTransactionId -> 51
              1: #valueMatches -> 72
              4: #allowRunJsScript -> 0
              5: #call -> 32
              6: #writeNumericParm -> 75
              7: .brand -> 77
              9: #sendResponse -> 59
             10: #timeZone -> 29
             11: #createFind -> 37
             12: #updateRecords -> 71
             13: #pendingImageFields -> 17
             14: #syncSemaphore -> 28
             15: #syncQueueLock -> 27
             16: #find -> 39
             17: #getFindRecordTypeInfoSet -> 45
             18: #inBuffer -> 8
             20: #getFileInfo -> 44
             21: #syncBuildRecord -> 66
             23: Connection -> 78
```
As noted before, the saved_class_variable_info has value 23 which does, indeed, reference Connection, my class name. 

The problem occurs when I use the codeCache from the compilation on the Isolate shown above on a different Isolate. The ScopeInfo heap object looks largely identical to the first Isolate, but the local names hash table looks like it's been rehashed (unsurprisingly):
```
0x27b95eb86f19: [NameToIndexHashTable]
 - FixedArray length: 259
 - elements: 79
 - deleted: 0
 - capacity: 128
 - elements: {
              0: #getTransactionId -> 51
              1: #valueMatches -> 72
              4: #allowRunJsScript -> 0
              5: #call -> 32
              6: #writeNumericParm -> 75
              7: .brand -> 77
              9: #sendResponse -> 59
             10: #timeZone -> 29
             11: #createFind -> 37
             12: #updateRecords -> 71
             13: #pendingImageFields -> 17
             14: #syncSemaphore -> 28
             15: #syncQueueLock -> 27
             16: #find -> 39
             17: Connection -> 78
             18: #inBuffer -> 8
             19: #getFindRecordTypeInfoSet -> 45
             20: #getUpdateValue -> 49
             21: #syncBuildRecord -> 66
             24: #syncImagineFileObj -> 24
```
Note that the class name Connection is now in slot 17 and slot 23 is unused. So now, when we try to create the class ScopeInfo for a stack trace, the 23 in saved_class_variable_info references an unused slot and I get a seg fault or a failed DCHECK(isString(name)), depending on the type of build.

Unfortunately, the fix seems beyond my meager skills. It seems that in deserialization for ScopeInfo, we would have to detect that we have a saved_class_variable_info and so need to recalculate saved_class_variable_info from the old value and the new hash table. But I'm not sure we can control the order in which the local names hash table and the ScopeInfo are deserialized and I'm not sure where in deserialization one would check for the ScopeInfo. 

Maybe someone more knowledgeable in the snapshot code could fix this relatively easily, suggest a work-around, or tell me what I'm doing wrong?

FWIW, this problem occurs for me on V8 13.1.139 and 13.6.233.2.

Thanks in advance!

alex...@gmail.com

unread,
Apr 9, 2025, 11:31:55 AMApr 9
to v8-users
FWIW, one "thought" I had on this was that if saved_class_variable_info were an Smi if the local names are inlined and a String reference, if not, then there would never be a need to fix anything up during deserialization as the String reference could be used to do a lookup in the local names hash table. But this is just kibitzing.

Toon Verwaest

unread,
Apr 9, 2025, 11:52:48 AMApr 9
to v8-u...@googlegroups.com
Thanks for this report! That sounds like a ScopeInfo deserialization bug. Presumably we rehash when we deserialize the NameToIndexHashTable but forget that we directly point to an entry from the ScopeInfo. Care to file a bug?

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/v8-users/afbfdb4c-81ea-4ce1-b3fc-db5aaea8d6b2n%40googlegroups.com.

alex...@gmail.com

unread,
Apr 9, 2025, 12:19:08 PMApr 9
to v8-users
Thanks Toon, will do.

Victor Gomes

unread,
Apr 9, 2025, 9:52:49 PM (14 days ago) Apr 9
to v8-u...@googlegroups.com
Thanks for the email, alexkodat.

It seems to be a bug when rehashing the table after code cache. Do you have a repro?
Could you please file a bug in https://issues.chromium.org component "Chromium > Blink > JavaScript > Runtime" and assign it to me.

Thanks,
- Victor

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.


Victor Gomes

Software Engineer

victo...@google.com


Google Germany GmbH

Erika-Mann-Straße 33

80636 München


Geschäftsführer: Paul Manicle, Halimah DeLaine Prado

Registergericht und -nummer: Hamburg, HRB 86891

Sitz der Gesellschaft: Hamburg


Diese E-Mail ist vertraulich. Falls Ssie diese fälschlicherweise erhalten haben sollten, leiten Sie diese bitte nicht an jemand anderes weiter, löschen Sie alle Kopien und Anhänge davon und lassen Sie mich bitte wissen, dass die E-Mail an die falsche Person gesendet wurde. 

     

This e-mail is confidential. If you received this communication by mistake, please don't forward it to anyone else, please erase all copies and attachments, and please let me know that it has gone to the wrong person.


Victor Gomes

unread,
Apr 9, 2025, 9:53:00 PM (14 days ago) Apr 9
to v8-u...@googlegroups.com
Please assign it to victo...@chromium.org

Igor Sheludko

unread,
Apr 9, 2025, 9:53:07 PM (14 days ago) Apr 9
to v8-u...@googlegroups.com
Hello!

Could you please file a bug report about this issue: https://issues.chromium.org/issues/new
Thank you!

--
--
v8-users mailing list
v8-u...@googlegroups.com
http://groups.google.com/group/v8-users
---
You received this message because you are subscribed to the Google Groups "v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+u...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/v8-users/459a487d-1515-47e7-b9ee-55a1c99ce5a3n%40googlegroups.com.


--

Igor Sheludko

Software Engineer

ish...@google.com


Google Germany GmbH

Erika-Mann-Straße 33

80636 München


Geschäftsführer: Paul Manicle, Liana Sebastian

Registergericht und -nummer: Hamburg, HRB 86891

Sitz der Gesellschaft: Hamburg


Diese E-Mail ist vertraulich. Falls sie diese fälschlicherweise erhalten haben sollten, leiten Sie diese bitte nicht an jemand anderes weiter, löschen Sie alle Kopien und Anhänge davon und lassen Sie mich bitte wissen, dass die E-Mail an die falsche Person gesendet wurde.

alex...@gmail.com

unread,
Apr 9, 2025, 10:41:12 PM (14 days ago) Apr 9
to v8-users
Victor, thanks for the quick response. I had created https://issues.chromium.org/issues/409512701 though I don't see how I can assign it to your or anyone else. Maybe I can't?

As far as a repro goes, I can easily reproduce with my executable but my company would not want me to send it to you :-( (nothing personal) so I'm going to have to put together a more standalone test. I'll have to figure out how to make and then load/run a snapshot, I guess, something I've never done before. Or maybe I can leverage some of the V8 unit tests. Regardless, this might take a bit of time. 

Reply all
Reply to author
Forward
0 new messages