ããããã£ã¨ã«ããã¼ããã£ã³ãã®çå¾ããã®è³ªåãããµã¨æãã¤ãããã¡ãã£ã¨ããéã³ã§ããã
ï¼ããã¦ãæ¸ãã¦ããå 容ã«èª¤è§£ããã£ããåªããæãã¦ãã ããï¼
p Object.new => #<Object:0x000055959ddf1910>
Rubyã®ãªãã¸ã§ã¯ãã®inspect表示ã®ããã©ã«ãã§åºã¦ããããã®16é²æ°ã¯ããã®ãªãã¸ã§ã¯ããç½®ããã¦ããã¡ã¢ãªã¢ãã¬ã¹ã®ãã¨ã ã¨ç¥ããã¦ããã
ã§ã¯ãå®éã«ãã®ã¡ã¢ãªã¢ãã¬ã¹ã«ãªãã¸ã§ã¯ããç½®ããã¦ãããã¨ã確ãããã«ã¯ï¼
ãã¦ã以ä¸ã®ã³ã¼ãã¯Linuxã§åãããã¨ã«ããã
String ãªãã¸ã§ã¯ãã§è©¦ãã¦ã¿ããã¨è¨ã£ã¦ããStringã®inspectã¯Objectã«å®ç¾©ããããã®ã§ã¯ãªããèªåã®ã¯ã©ã¹ã§å®ç¾©ãã¦ããã®ã§ãã¾ãã¯ããããç¡å¹ã«ãããã以ä¸ã®ãããªæ¹æ³ã§ Object#inspect
ãå¼ã¶ããã«å¤æ´ã§ããã
class String # å ã«æ»ãããããæ¬æ¥ã®inspectãå¥åã§ä¿å alias orig_inspect inspect def inspect super end end
String ã®inspect表示ãå¤ãã£ã¦ããã®ã確ãããã
str = "Hola, mundo" => #<String:0x000055959d972038>
ãã®ã¢ãã¬ã¹ã«ããèªåã®ã¡ã¢ãªã®ç¶æ³ãè¦ã¦ã¿ãããLinuxã§ããã°ã /proc/self/mem
ãèªã¿è¾¼ããã¨ã§ç¢ºèªãã§ããã
ãã®procã£ã¦ãªãã ããï¼ ã¨è©³ããç¥ãããåãã«ã¯ man 5 proc
ãªã©ãèªãã§ããããã¨ã¨ãã¦ã /proc
ã¨ãããã¡ã¤ã«ã·ã¹ãã ã®ä¸ããããã»ã¹ã®æ
å ±ãåå¾ã§ããã¨ãããããã®ç解ã§ä¸æ¦ã¯å
ã«é²ããã
ã¨ãããã¨ã§ /proc/self/mem
ãèªã¿è¾¼ã㧠0x000055959d972038
åã ãseekãããRubyã ã¨ãã®è¡¨ç¾ã®ã¾ã¾æ°å¤ã¨èªèãã¦ãããã®ã§ä¾¿å©ã ãã
mem = open("/proc/self/mem") mem.seek 0x000055959d972038
ãã®å ã®ä½æ¥ããããã¥ããã®ã§ãString#inspectã®å®ç¾©ãå ã«æ»ãã
class String alias inspect orig_inspect end
ãã¦ãã¡ã¢ãªããã¨ãããã32ãã¤ãï¼ãªãããã®æ°å¤ã¯åã§æ±ºãã¾ããï¼ã»ã©èªã¿è¾¼ãã§ã¿ãã
dump = mem.read 32 => "e\xC0R\x00\x00\x00\x00\x00`hT\x9D\x95U\x00\x00Hola, mundo\x00\x00\x00\x00\x00"
ãªãã¨ãªããå
ã»ã©ã®æåå Hola, mundo
ãæ ¼ç´ããã¦ãããããªæ°ãããããå®éã©ãããã¬ã¤ã¢ã¦ãã«ãªã£ã¦ãããã¨ããã¨ã
Ruby 3.0.2 ã§ã¯æååã表ãæ§é ä½ RString
ã¯æ¬¡ã®å®ç¾©:
struct RString { struct RBasic basic; union { struct { long len; char *ptr; union { long capa; VALUE shared; } aux; } heap; char ary[RSTRING_EMBED_LEN_MAX + 1]; } as; };
RBasicã¯æ¬¡ã®å®ç¾©:
struct RUBY_ALIGNAS(SIZEOF_VALUE) RBasic { VALUE flags; /**< @see enum ::ruby_fl_type. */ const VALUE klass; #ifdef __cplusplus // ... ã¯é¢ä¿ãªãã®ã§é£ã°ãã¾ã #endif };
VALUE ã¯ã ããã uintptr_t
ã®ãã¨ãããã
typedef uintptr_t VALUE;
ãã«ãã®ç°å¢ã«ãã£ã¦å½ç¶è¥å¹²å¤ãã£ã¦ããããçè ã® x86-64 ãªLinuxç°å¢ã§ã¯ãã®å®ç¾©ã¨èãã¦è¯ãã ããã
ã¨ãããã¨ã¯ãã¡ã¢ãªããåãåºãããã¤ããªåããã¨ãããã以ä¸ã®è¦é 㧠unpack ããã°ã
# VALUE VALUE char[] ã¨ã㦠unpack ãã dump.unpack "Q! Q! Z*" => [5423205, 94101078042720, "Hola, mundo"]
... ã¨ããããã«ã¡ã¢ãªä¸ã®æååãåãåºããã
ã¡ãªã¿ã«ã RSTRING_EMBED_LEN_MAX
ã¨ããå®æ°ããããã¨ãããããç¨åº¦ä»¥ä¸é·ãæååã ã¨RStringæ§é ä½ã®ä¸ã«ã¯åã¾ããªããã¨ãæ³åãããã
å®éã«ãã£ã¦ã¿ããã
class String; def inspect; super; end; end str2 = "very long string " * 100 => #<String:0x000055959de10180> # æ»ã class String; alias inspect orig_inspect; end
0x000055959de10180
ãèªã¿è¾¼ãã
mem.close mem = open("/proc/self/mem") mem.seek 0x000055959de10180 dump = mem.read 32 => "e P\x00\x00\x00\x00\x00`hT\x9D\x95U\x00\x00\xA4\x06\x00\x00\x00\x00\x00\x00`\xE2\xE7\x9D\x95U\x00\x00"
ä¸è¿°ãã RString, RBasic ã®å®ç¾©ãåèã«ãã¦ãããããã¬ã¤ã¢ã¦ãã ã¨ãã¦unpackãã¦ã¿ãã
struct _RString { VALUE flags; VALUE klass; struct { long len; char *ptr; // ... } heap }
dump.unpack "Q! Q! l! Q!" => [5251173, 94101078042720, 1700, 94101087707744]
1700
ã¨ããã®ãæååã®é·ãã«ã¡ããã¨å¯¾å¿ãã¦ããã
str2.size
=> 1700
ã§ãã¢ãã¬ã¹ 94101087707744
*1ãã 1700 ãã¤ãèªã¿è¾¼ã¿ãããã«å½è©²ã®æååããããã¨ã確èªãããã¨ãã§ããã
mem.seek 94101087707744 mem.read 1700 => "very long string very long string very long string... "