DOKK / manpages / debian 12 / libdevel-mat-perl / Devel::MAT::UserGuide::IdentifyingAnSV.3pm.en
Devel::MAT::UserGuide::IdentifyingAnSV(3pm) User Contributed Perl Documentation Devel::MAT::UserGuide::IdentifyingAnSV(3pm)

"Devel::MAT::UserGuide::IdentifyingAnSV" - working out what an SV actually is

Often when analysing a heap dump file to determine the cause of a memory issue the problem can be narrowed down to a single SV at a particular address. Even though the SV is often printed with a general type name, this simple address as a raw hex number does not directly help to find what part of the program is actually responsible for this SV.

To find out more about what the SV is, in terms of what things can reach it, use the "identify" command on its address.

  pmat> identify 0x6a47708

The output will form a tree of back-references, leading down ultimately to known roots of the program; fixed points in the perl interpreter.

Sometimes this will be a short and simple tree leading directly to a known root:

  pmat> identify 0xfb4770
  HASH(0) at 0xfb4770=strtab is:
  XXthe shared string table HV

In this case, the SV is actually a known root directly; a particularly simple result.

Other times this may be a longer less-direct path, perhaps having multiple branches:

  pmat> identify 0x72a7140
  ARRAY(457025) at 0x72a7140 is:
  XX(via RV) value {error} of HASH(3) at 0x490ea40, which is:
    XX(via RV) value {events} of HASH(8)=Mojo::Redis2 at 0x490e0b0, which is:
      XX(via RV) value {ws_redis_master} of HASH(4) at 0x3ebef40, which is:
        XX(via RV) the lexical $instances at depth 1 of CODE(PP) at 0x4264c38, which is:
        X XXthe symbol '&Binary::WebSocketAPI::v3::Wrapper::Streamer::shared_redis'
        XX(via RV) the lexical $instances at depth 1 of CODE(PP) at 0x42504a0, which is:
        X XXthe symbol '&Binary::WebSocketAPI::v3::Instance::Redis::instances'
        XX(via RV) the lexical $instances at depth 1 of CODE(PP) at 0x4257500, which is:
        X XXthe symbol '&Binary::WebSocketAPI::v3::Instance::Redis::redis_pricer'
        XX(via RV) the lexical $instances at depth 1 of CODE(PP) at 0x4264920, which is:
        X XXthe symbol '&Binary::WebSocketAPI::Plugins::Helpers::ws_redis_slave'
        XX(via RV) the lexical $instances at depth 1 of CODE(PP) at 0x4263eb8, which is:
          XXthe symbol '&Binary::WebSocketAPI::Plugins::Helpers::ws_redis_master'

Here, the named symbols count as well-known roots for the purpose of identifying SVs. The SV in question has been identified as reachable via a chain of keys, coming from a hash stored in a lexical variable named $instances captured by of five different functions.

Sometimes, the path from a given SV to the known roots is somehow self-referential, and needs to refer back to itself. This is done with lettered markers.

  pmat> identify 0x55d00c107218
  REF() at 0x55d00c107218 is:
  XXelement [0] of ARRAY(1) at 0x55d00c106f90, which is (*A):
    XX(via RV) value {cycle} of HASH(1) at 0x55d00c1240c8, which is:
      XX(via RV) element [0] of ARRAY(1) at 0x55d00c106f90, which is:
      X XXalready found as *A
      XX(via RV) the lexical $loop at depth 1 of CODE() at 0x55d00c107230=main_cv, which is:
        XXthe main code

In each case, the output should at least help work out what any given SV is by noting what references it, recursively, up to the roots of the interpreter.

Paul Evans <leonerd@leonerd.org.uk>

2023-03-26 perl v5.36.0