Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: e5c29fb322200872ae3cce866c62c7f6529103fc
      
https://github.com/WebKit/WebKit/commit/e5c29fb322200872ae3cce866c62c7f6529103fc
  Author: Mark Lam <[email protected]>
  Date:   2026-08-26 (Wed, 26 Aug 2026)

  Changed paths:
    M Source/JavaScriptCore/CMakeLists.txt
    A Source/JavaScriptCore/Configurations/Mya.xcconfig
    A Source/JavaScriptCore/Configurations/TestLibJSCTools.xcconfig
    A Source/JavaScriptCore/Configurations/libJavaScriptCoreTools.xcconfig
    M Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
    M Source/JavaScriptCore/Scripts/process-entitlements.sh
    A Source/JavaScriptCore/corpse/CMakeLists.txt
    A Source/JavaScriptCore/corpse/CorpseAddress.h
    A Source/JavaScriptCore/corpse/CorpseByteParser.cpp
    A Source/JavaScriptCore/corpse/CorpseByteParser.h
    A Source/JavaScriptCore/corpse/CorpseClient.cpp
    A
Source/JavaScriptCore/corpse/CorpseClient.h
    A Source/JavaScriptCore/corpse/CorpseError.cpp
    A Source/JavaScriptCore/corpse/CorpseError.h
    A Source/JavaScriptCore/corpse/CorpseExportsTrie.cpp
    A Source/JavaScriptCore/corpse/CorpseExportsTrie.h
    A Source/JavaScriptCore/corpse/CorpseProcess.cpp
    A Source/JavaScriptCore/corpse/CorpseProcess.h
    A Source/JavaScriptCore/corpse/CorpseRegion.cpp
    A Source/JavaScriptCore/corpse/CorpseRegion.h
    A Source/JavaScriptCore/corpse/CorpseSnapshot.cpp
    A Source/JavaScriptCore/corpse/CorpseSnapshot.h
    A Source/JavaScriptCore/corpse/CorpseSymbol.cpp
    A Source/JavaScriptCore/corpse/CorpseSymbol.h
    A Source/JavaScriptCore/corpse/CorpseThread.cpp
    A Source/JavaScriptCore/corpse/CorpseThread.h
    A Source/JavaScriptCore/corpse/testLibJSCTools.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseAddressTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseAddressTest.h
    A
Source/JavaScriptCore/corpse/tests/CorpseByteParserTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseByteParserTest.h
    A Source/JavaScriptCore/corpse/tests/CorpseExportsTrieTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseExportsTrieTest.h
    A Source/JavaScriptCore/corpse/tests/CorpseProcessTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseProcessTest.h
    A Source/JavaScriptCore/corpse/tests/CorpseRegionTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseRegionTest.h
    A Source/JavaScriptCore/corpse/tests/CorpseSnapshotTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseSnapshotTest.h
    A Source/JavaScriptCore/corpse/tests/CorpseSymbolTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseSymbolTest.h
    A Source/JavaScriptCore/corpse/tests/CorpseThreadTest.cpp
    A Source/JavaScriptCore/corpse/tests/CorpseThreadTest.h
    A Source/JavaScriptCore/corpse/tests/LibJSCToolsTestUtilities.cpp
    A
Source/JavaScriptCore/corpse/tests/LibJSCToolsTestUtilities.h
    A Source/JavaScriptCore/mya/mya.cpp
    M Source/JavaScriptCore/shell/CMakeLists.txt
    M Source/JavaScriptCore/shell/PlatformCocoa.cmake
    M Tools/CISupport/ews-build/steps.py
    M Tools/Scripts/run-javascriptcore-tests
    M Tools/Scripts/webkitperl/BuildSubproject.pm
    M Tools/Scripts/webkitpy/common/config/ports.py
    M Tools/Scripts/webkitpy/common/config/ports_unittest.py

  Log Message:
  -----------
  Introducing Mya, a MemorY Analyzer, and libJavaScriptCoreTools.
https://bugs.webkit.org/show_bug.cgi?id=321334
rdar://184365506

Reviewed by Elliott Williams and Dan Hecht.

Mya (pronounced like Maya) is a new command line tool for examining the JSC and
WebKit memory use in a running process.  It attaches to a target by PID and 
captures
snapshots of its memory (read-only Mach corpses of the process), and then 
enables
queries on these snapshots via a REPL.

Here is an example user work
flow:

    # mya --help                    // Prints help text and exit.

    # mya --pid 12345               // Attach to the process, and take a 
snapshot.
    Attached to 12345
    Captured Snapshot #1 of 12345

    >>> snapshot list               // Lists all existing snapshots.
    #1: pid 12345 ...               // Only one so far.

    >>> snapshot                    // Take another snapshot, and switch to it.
    Captured Snapshot #2 of 12345   // Capture and switch to snapshot 2.

    >>> status                      // Shows current pid and snapshot being 
examined.
    Using snapshot 2 of pid 12345   // The snapshot command above switched us.

    >>> snapshot --pid 23456
    Attached to 23456               // Attach and switch to this second process.
    Captured Snapshot #3 of 23456   // Capture and switch to snapshot 3.

    >>> snapshot list               // Lists all existing snapshots.
    #1: pid 12345 ...
    #2: pid 12345 ...
    #3: pid 23456
...

    >>> status                      // Shows current pid and snapshot being 
examined.
    Using snapshot 2 of pid 23456   // Note: the snapshot command above 
switched us.

    >>> detach                      // Detach from the current process.
    Detached from 23456

    >>> snapshot                    // Fails. No attached process.
    Unable to capture snapshot. Not attached to any process. Use `attach` 
command or specify `--pid` argument for the snapshot command.

    >> snapshot info 1              // Show info on snapshot 1.
    ...

    >>> snapshot delete 2           // Delete snapshot 2.
    ...

    >>> snapshot diff 1 3           // Diff between snapshots 1 and 3. Not yet 
implemented.
    ...

    >> snapshot 1                   // Select snapshot 1 for analysis.

    >>> thread list                 // Prints info on all thread in the current 
snapshot.
    Threads in snapshot #1 (pid 12345):
      INDEX  TID        STATE    USER(ms)   SYS(ms) 
SP           STACK                       SIZE  PAGES  RESIDENT  DIRTY  NAME
          1  0x12278c6  halted  23645.003  2937.065  0x16b7361e0  
0x16af3c000-0x16b738000  7.98 MB    511         7      7  -
          2  0x12278c7  halted     56.147    23.816  0x167386aa0  
0x167304000-0x16738c000   544 KB     34         1      1  WebCore: ServiceWorker
          3  0x12278c8  halted      0.211     0.472  0x105986b30  
0x105904000-0x10598c000   544 KB     34         1      1  -

    >>> p/x &g_config              // Prints the address of the g_config record.
    &g_config = 0x1f48e0000

The corpse management and analysis machinery lives in libJavaScriptCoreTools, a 
new
static library built alongside the JavaScriptCore framework. Clients that need 
to do
this type of snapshot analysis can link against it.  By design, the corpse 
management
and analysis code is not linked and packaged with the JavaScriptCore framework 
by
default because they are not needed
there.

libJavaScriptCoreTools provides abstractions like Address, Process, Snapshot, 
Thread,
Region, Symbol, etc. for inspecting and analyzing such WebKit and JSC corpses.  
Corpse
Addresses are numbered based on the target process' address space mapping, not 
the
client tool like mya.  Currently, libJavaScriptCoreTools copies over memory 
from the
corpse for inspection as an initial bootstrap implementation.  In subsequent 
patches,
we will introduce a Memory Manager that will make reading corpse memory more 
efficient.

Symbol lookup resolves a name to an address by walking the dyld exports trie of
each image loaded in the corpse. That needs no cooperation from the target and 
no
debug information, but it only finds exported symbols.

Everything read out of a corpse is untrusted input: a corrupted target could 
otherwise
steer mya into unbounded work or bad reads. The parsing paths therefore bound 
the work
they will do and reject implausible sizes, counts, and offsets
rather than trusting what
the target claims.

mya and libJavaScriptCoreTools are only for Apple platforms, since they are 
built on
Mach task APIs, which are only available on Apple platforms.

Also, it is not a goal to support analysis of Rosetta processes.  Some subset of
functionality may still work, but only on a WYSIWYG basis.

Tests: Source/JavaScriptCore/corpse/tests/

testLibJSCTools is a new test tool for libJavaScriptCoreTools, built with the 
other
JSC test tools and run by:

    run-javascriptcore-tests --testlibjsctools

A task may take a corpse of itself with no entitlement and no privilege, and the
tests are built on that: they snapshot the running test process and check what 
the
corpse reports against what that process already knows about itself. A symbol
resolved out of the corpse, for instance, has to land on the address this 
process
uses for it. The suites are:

    ByteParser   ULEB128 and C string decoding, including the truncated and out 
of
 
range encodings that untrusted data can hold.
    ExportsTrie  terminal and edge decoding for every export kind and flag, the
                 malformed tries that a corrupt corpse can present, and that a
                 cyclic trie still terminates. Also fuzzed from a fixed seed on
                 every run, under a watchdog, because the decoder's contract is 
to
                 bound its work on any input at all.
    Address      null, ordering, arithmetic, and the ptrauth and top-byte 
stripping
                 that a pointer out of a corpse needs.
    Process      attach, detach, re-attach, a pid that has exited, and a target
                 running under Rosetta translation.
    Snapshot     validity, identifier assignment, and that repeatedly 
snapshotting
                 leaves no Mach port behind.
    Region       a mapping of known size and residency, an unmapped hole, and an
                 address inside the shared cache submap.
    Thread       thread
names and their truncation, and that a thread's stack
                 pointer lies inside the stack region reported for it.
    Symbol       g_config, malloc and environ resolved out of a corpse of this
                 process, each compared against the address it has locally, plus
                 the names that are deliberately not found: a symbol hidden from
                 the linker, and a name given with its underscore already 
attached.

For the build, libJavaScriptCoreTools, mya, and testLibJSCTools are 
deliberately put in
jsc's dependency closure in the JavaScriptCore_executables XBS project.  This 
is so that
they can piggy-back off of jsc shell's build phase i.e. only trigger a build 
after
JavaScriptCore.framework is done building, and trigger an install like the jsc 
shell is
(albeit to their respective install destinations, which may defer).

* Source/JavaScriptCore/CMakeLists.txt:
* Source/JavaScriptCore/Configurations/Mya.xcconfig: Added.
*
Source/JavaScriptCore/Configurations/TestLibJSCTools.xcconfig: Added.
* Source/JavaScriptCore/Configurations/libJavaScriptCoreTools.xcconfig: Added.
* Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj:
* Source/JavaScriptCore/Scripts/process-entitlements.sh:
* Source/JavaScriptCore/corpse/CMakeLists.txt: Added.
* Source/JavaScriptCore/corpse/CorpseAddress.h: Added.
* Source/JavaScriptCore/corpse/CorpseByteParser.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseByteParser.h: Added.
* Source/JavaScriptCore/corpse/CorpseClient.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseClient.h: Added.
* Source/JavaScriptCore/corpse/CorpseError.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseError.h: Added.
* Source/JavaScriptCore/corpse/CorpseExportsTrie.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseExportsTrie.h: Added.
* Source/JavaScriptCore/corpse/CorpseProcess.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseProcess.h: Added.
*
Source/JavaScriptCore/corpse/CorpseRegion.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseRegion.h: Added.
* Source/JavaScriptCore/corpse/CorpseSnapshot.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseSnapshot.h: Added.
* Source/JavaScriptCore/corpse/CorpseSymbol.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseSymbol.h: Added.
* Source/JavaScriptCore/corpse/CorpseThread.cpp: Added.
* Source/JavaScriptCore/corpse/CorpseThread.h: Added.
* Source/JavaScriptCore/corpse/testLibJSCTools.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseAddressTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseAddressTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseByteParserTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseByteParserTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseExportsTrieTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseExportsTrieTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseProcessTest.cpp: Added.
*
Source/JavaScriptCore/corpse/tests/CorpseProcessTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseRegionTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseRegionTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseSnapshotTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseSnapshotTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseSymbolTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseSymbolTest.h: Added.
* Source/JavaScriptCore/corpse/tests/CorpseThreadTest.cpp: Added.
* Source/JavaScriptCore/corpse/tests/CorpseThreadTest.h: Added.
* Source/JavaScriptCore/corpse/tests/LibJSCToolsTestUtilities.cpp: Added.
* Source/JavaScriptCore/corpse/tests/LibJSCToolsTestUtilities.h: Added.
* Source/JavaScriptCore/mya/mya.cpp: Added.
* Source/JavaScriptCore/shell/CMakeLists.txt:
* Source/JavaScriptCore/shell/PlatformCocoa.cmake:
* Tools/CISupport/ews-build/steps.py:
* Tools/Scripts/run-javascriptcore-tests:
*
Tools/Scripts/webkitperl/BuildSubproject.pm:
* Tools/Scripts/webkitpy/common/config/ports.py:
* Tools/Scripts/webkitpy/common/config/ports_unittest.py:

Canonical link: 
https://flagged.apple.com:443/proxy?t2=DR1G5N9Et8&o=aHR0cHM6Ly9jb21taXRzLndlYmtpdC5vcmcvMzE5OTA0QG1haW4=&emid=69bfbc02-6bb5-4c45-9439-d54a33ce22f5&c=11



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to