• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..31-Mar-2022-

replay/H03-May-2022-1,4461,061

FdPrintf.cppH A D31-Mar-20224.8 KiB200152

FdPrintf.hH A D31-Mar-20221.1 KiB288

LogAlloc.cppH A D31-Mar-20227.5 KiB237166

READMEH A D31-Mar-20224 KiB9675

moz.buildH A D31-Mar-2022685 3124

README

1Logalloc is a replace-malloc library for Firefox (see
2memory/build/replace_malloc.h) that dumps a log of memory allocations to a
3given file descriptor or file name. That log can then be replayed against
4Firefox's default memory allocator independently or through another
5replace-malloc library, allowing the testing of other allocators under the
6exact same workload.
7
8To get an allocation log the following environment variable when starting
9Firefox:
10  MALLOC_LOG=/path/to/log-file
11  or
12  MALLOC_LOG=number
13
14When MALLOC_LOG is a number below 10000, it is considered as a file
15descriptor number that is fed to Firefox when it is started. Otherwise,
16it is considered as a file name.
17
18As those allocation logs can grow large quite quickly, it can be useful
19to pipe the output to a compression tool.
20
21MALLOC_LOG=1 would send to Firefox's stdout, MALLOC_LOG=2 would send to
22its stderr. Since in both cases that could be mixed with other output
23from Firefox, it is usually better to use another file descriptor
24by shell redirections, such as:
25
26  MALLOC_LOG=3 firefox 3>&1 1>&2 | gzip -c > log.gz
27
28(3>&1 copies the `| gzip` pipe file descriptor to file descriptor #3, 1>&2
29then copies stderr to stdout. This leads to: fd1 and fd2 sending to stderr
30of the parent process (the shell), and fd3 sending to gzip.)
31
32Each line of the allocations log is formatted as follows:
33  <pid> <tid> <function>([<args>])[=<result>]
34where <args> is a comma separated list of values. The number of <args> and
35the presence of <result> depend on the <function>.
36
37Example log:
38  18545 18545 malloc(32)=0x7f90495120e0
39  18545 18545 calloc(1,148)=0x7f9049537480
40  18545 18545 realloc(0x7f90495120e0,64)=0x7f9049536680
41  18545 18545 posix_memalign(256,240)=0x7f9049583300
42  18545 18545 jemalloc_stats()
43  18545 18545 free(0x7f9049536680)
44
45This log can be replayed with the logalloc-replay tool in
46memory/replace/logalloc/replay. However, as the goal of that tool is to
47reproduce the recorded memory allocations, it needs to avoid as much as
48possible doing its own allocations for bookkeeping. Reading the logs as
49they are would require data structures and memory allocations. As a
50consequence, the logs need to be preprocessed beforehand.
51
52The logalloc_munge.py script is responsible for that preprocessing. It simply
53takes a raw log on its stdin, and outputs the preprocessed log on its stdout.
54It replaces pointer addresses with indexes the logalloc-replay tool can use
55in a large (almost) linear array of allocation tracking slots (prefixed with
56'#'). It also replaces the pids with numbers starting from 1 (such as the
57first seen pid number is 1, the second is 2, etc.).
58
59The above example log would become the following, once preprocessed:
60  1 1 malloc(32)=#1
61  1 1 calloc(1,148)=#2
62  1 1 realloc(#1,64)=#1
63  1 1 posix_memalign(256,240)=#3
64  1 1 jemalloc_stats()
65  1 1 free(#1)
66
67The logalloc-replay tool then takes the preprocessed log on its stdin and
68replays the allocations printed there, but will only replay those with the
69same process id as the first line (which normally is 1).
70
71As the log files are simple text files, though, it is easy to separate out
72the different processes log with e.g. grep, and feed the separate processes
73logs to logalloc-replay.
74
75The logalloc-replay program won't output anything unless jemalloc_stats
76records appears in the log. You can expect those to be recorded when going
77to about:memory in Firefox, but they can also be added after preprocessing.
78
79Here is an example of what one can do:
80
81  gunzip -c log.gz | python logalloc_munge.py | \
82  awk '$1 == "2" { print $0 } !(NR % 10000) { print "2 1 jemalloc_stats()" }' | \
83    ./logalloc-replay
84
85The above command replays the allocations of process #2, with some stats
86output every 10000 records.
87
88The logalloc-replay tool itself being hooked with replace-malloc, it is possible
89to set LD_PRELOAD/DYLD_INSERT_LIBRARIES/MOZ_REPLACE_MALLOC_LIB and replay a log
90through a different allocator. For example:
91
92  LD_PRELOAD=libreplace_jemalloc.so logalloc-replay < log
93
94Will replay the log against jemalloc4 (which is, as of writing, what
95libreplace_jemalloc.so contains).
96