Tribler / tribler

Privacy enhanced BitTorrent client with P2P content discovery
https://www.tribler.org
GNU General Public License v3.0
4.86k stars 451 forks source link

Perform light-weight memory dumps with gc #3603

Closed qstokkink closed 3 months ago

qstokkink commented 6 years ago

As the meliae library keeps giving us trouble, we can switch over to the built-in gc library for object leak inspection. The following snippet will already do the dirty work:

import gc, sys
obj_dump = gc.get_objects()
out = {}
for obj in obj_dump:
    out[type(obj)] = out.get(type(obj), 0) + 1
print >> sys.stderr, out

This will produce something like:

``` { :2, :1, :1, :2, :1, :1, :2, :88, :1641, :2, :10, :18, :2, :1, :2, :1, :21, :159, :12, :7, :1, :1, :1, :4, :1, :1, :2, :1, :328, :1, :10, :44, :1, :1, :1, :1, :6, :3, :1, :6, :12913, :28, :1, :96, :47, :24, :1, :1, :75, :1, :2, :1, :1, :19, :5, :1, :2, :35, :1, :3, :727, :2, :6, :1, :1, :42, :1, :1, :44, :318, :1, :5, :1, :2, :3, :88, :30, :2, :1, :3016, :1, :1, :1, :7, :1, :132, :6, :114, :2, :1, :2136, :62, :1, :1, :9, :1, :1, :2, :3030, :19, :6, :1, :1, :2, :3, :8, :1, :2, :12, :396, :1, :1, :1, :2, :1, :2, :1, :1, :20, :3, :1, :29, :2, :1, :1, :12, :1, :930, :8, :1, :1, :2, :3, :84, :4, :2, :1, :37866, :127, :1, :1, :4, :18, :1, :63, :16, :1, :5298, :1, :5, :1, :1, :66, :6, :2, :10, :1, :5, :1, :4949, :76, :12, :5, :1, :3, :108, :1, :4, :208, :452, :3, :12, :1, :1, :1, :1, :1, :1, :7, :1, :1, :1, :3, :17, :1, :3, :1, :1, :2, :14, :12, :1, :9, :4, :2, :18, :1, :9, :1, :1, :72, :6, :1, :4, :3, :25, :3, :1, :1, :4, :1, :31, :1, :2, :1, :4, :1, :1, :7, :1, :1, :1, :2146, :2, :3, :1, :1, :84, :8, :155, :1, :3, :12, :968, :43, :1, :3, :1, :1, :34, :1, :1, :110, :1, :1, :1, :1, :35, :4, :2, :3, :1, :1, :3, :1, :1, :13, :48, :1, :1, :1, :1, :1, :1, :1, :1, :3, :1, :1, :1, :2, :1, :7, :268, :1, :7, :1, :1, :1, :6, :13, :3, :1, :11, :2, :2, :2, :3, :1, :1, :1, :1, :1, :1, :1, :50, :1, :1, :1, :1, :1, :1, :16, :2, :1, :27, :43, :2, :1, :1, :1, :1, :1, :4, :1, :1, :1, :1, :10, :5, :8, :5, :6, :69, :2, :52, :3, :2924, :1, :27, :2, :2, :5, :1, :1, :8, :1, :9, :47, :1, :2, :1, :1, :2, :3, :1, :1, :2, :108, :1, :1, :2, :1, :83, :1, :1, :1, :1, :10, :1, :1, :3, :3, :2, :1, :39, :6, :21, :1, :1, :1, :1, :1, :6, :1, :5, :2, :8, :1, :30, :1, :11, :1, :3, :6, :6761, :1, :1, :5, :1, :1, :11, :7, :1, :2, :1, :2896, :1, :91, :1, :3, :36, :15, :1, :5, :22462, :108, :2, :1, :1, :3, :1, :3, :1, :3, :21377, :1, :1, :145, :1, :24, :6, :46, :316, :1, :1, :2, :1, :1, :1, :1, :18, :10, :1, :112, :4, :1, :1, :1, :1, :16, :3, :1, :1, :1, :15, :16, :1, :284, :29, :1, :1, :1, :2, :4, :2, :23, :1, :2, :1, :1, :1, :19, :1, :1, :1, :1, :27, :2, :1, :11, :5, :3, :2, :24, :8750, :3, :1, :56, :42, :1, :1, :1, :1, :1, :5, :1, :1, :200, :1, :1, :92, :12, :6, :1, :13, :1, :2, :15, :1, :1, :1, :2, :1, :3, :20, :1, :4, :1, :1, :3, :1, :1, :10, :1, :6, :1, :1, :2, :1, :2, :3, :1, :2, :2, :1, :1, :12, :6, :3, :1, :1, :1, :1, :6, :144, :3, :124, :2, :1, :1, :3, :7, :1, :1, :2, :1, :1, :1, :2, :22, :1, :1, :2, :1, :27, :3, :1, :1, :4, :1, :62, :10, :42, :1, :10, :4, :18, :1, :1, :1, :14, :2, :1, :31, :3, :2, :3, :2, :11, :1630, :2, :1, :1, :31, :200, :2, :1, :13, :1, :1, :107, :2, :2, :1, :1, :1, :4, :4, :280, :52, :1, :24, :389, :1, :1, :31, :1, :37, :1, :1, :8, :28, :79, :8, :35, :19, :1, :10, :10, :3, :12, :6, :1, :6, :1, :3, :1, :1, :10, :1, :1, :1, :1, :3, :1, :131, :1, :2, :1, :6, :7, :1, :11, :19, :10, :1, :1, :1, :3, :1, :1, :2, :29, :1, :1, :222, :34, :2, :1, :43, :2, :2, :1, :1, :4, :1, :4, :6, :2, :2, :1, :6, :6, :2, :1, :1, :2, :1, :1, :64, :4, :1, :21, :1, :2, :1, :132, :18, :1, :2, :1, :274, :55, :1, :21, :25, :68, :1, :1, :1, :1, :44, :15, :6, :1, :1, :920, :222, :1, :52, :3, :2, :6, :36, :3, :1, :1, :1, :5 } ``` Or, when used on the GUI: ``` { :1, :6, :8, :2, :4, :1, :2, :1, :1682, :1, :1, :25, :1, :3, :1, :6, :1, :1, :2, :2, :3, :1, :4, :1, :6, :30, :3, :9, :1, :664, :12, :2, :7, :3, :2, :19, :1, :4, :1, :20, :16660, :2, :368, :1, :4, :2, :5, :2, :3, :1, :9, :312, :3, :4, :28, :5, :1, :1, :1, :2, :2536, :1, :55, :6, :5, :2, :2, :1, :6, :5053, :201, :2, :3, :2, :19, :10, :10, :65, :3198, :1, :12, :1, :3, :1, :11, :2, :1, :4, :1, :6, :1, :1, :2, :1, :3, :8, :6, :25, :2, :527, :1, :4, :3, :7, :6, :1, :19, :8, :9, :4, :1, :27, :498, :1, :1, :2, :2, :1, :7, :1, :2618, :61, :2, :3, :3, :2, :35, :5, :195, :4, :1, :1, :2, :96, :3, :100, :21, :4, :19, :1, :3, :3, :1, :4, :1, :20, :10, :5, :69, :36, :6, :23, :1, :138, :19, :1, :676, :4, :4, :78, :2, :3, :9, :1, :3, :654, :31, :4, :2, :4, :66, :2, :1, :18, :2, :3, :1, :3, :16, :15, :1, :10, :9, :128, :3, :44, :1, :1, :7, :8, :2, :1, :3, :7, :15, :84, :3, :2, :6, :148, :3, :22, :5, :2, :23, :10, :1, :5, :6, :1, :1, :1, :1, :3, :1, :1, :10, :4, :186, :3, :1, :3, :1, :1, :1, :5, :4, :1, :1, :4, :1, :3, :2, :2, :221, :4, :2, :7, :6, :43, :17, :88, :1, :2, :1, :4, :8, :1643, :6, :2, :1, :1, :1, :7, :2, :5, :2, :3, :2, :2, :7, :2, :3, :98, :1, :13, :5, :1, :1, :8, :1, :1, :574, :7, :2, :1, :1, :1, :1, :5, :350, :4, :10, :2, :1, :4, :18, :6, :11, :1, :1, :29, :4, :4, :146, :103, :1, :3, :5, :1, :3, :1, :143, :1, :3, :2, :4, :2, :1, :9, :6, :2, :2, :1, :1, :1, :32, :1, :1, :7, :4, :1, :2, :8, :1, :1, :57, :1, :4, :3, :6, :60, :1, :1, :23, :3, :19, :2, :4, :1, :2, :1, :1, :1, :8, :5, :121, :28, :1, :1, :2, :8, :9, :330, :2, :3, :5615, :2, :1, :3, :2, :1, :8471, :1, :1621, :1, :1, :4, :1, :1, :2, :3, :9, :1, :2, :2, :9175, :1, :4, :12, :9, :3, :3, :2, :4, :2, :2, :1, :19635, :13, :1, :4, :1, :4, :6, :1, :43, :16, :1, :6, :7, :2, :7, :13, :4, :2, :1, :1, :1, :3, :5, :1, :1, :8, :14, :1, :2, :1, :439, :1, :90, :2, :26, :1, :11, :4, :1, :5, :13, :9, :2, :4, :7, :1, :2, :2, :6, :1, :2, :1, :8, :1, :1, :3, :8, :6, :1, :2, :6, :1, :2, :163, :1, :5, :2, :3863, :1, :1, :6, :3, :4, :3, :1, :2, :1, :1, :1, :2, :1, :356, :16, :5, :1, :1, :1, :5, :2, :38, :1, :3, :1, :1, :20, :1, :2, :1, :3, :3, :1, :1, :2, :3, :1, :2, :3, :2, :18, :1, :24, :1, :1, :1, :2, :8, :1, :1, :2, :2, :15, :7, :62, :265, :107, :11, :34, :1, :1, :4, :5, :4, :4, :5, :8, :1, :1, :4, :1, :4, :9, :3, :2, :3, :10, :82, :3, :30, :19, :3, :1, :13, :17, :6, :144, :10, :2, :1, :10, :1, :1, :2, :1, :3, :3, :1, :1, :1, :1, :2, :2, :669, :3, :1, :1, :10, :8, :5, :5, :263, :3, :3, :4, :1, :5, :1, :20, :5, :2, :3, :1, :4, :9, :1, :4, :5, :8, :1, :758, :2, :3, :6, :3, :1, :1, :7, :93, :175, :101, :2, :1, :1, :1, :18, :5, :4, :4, :7, :2, :1, :1, :1, :7, :3, :1, :1, :1, :1, :76, :2, :7, :3, :1, :1, :2, :3, :2, :1, :2, :1, :3, :1, :5, :15, :9, :1, :2, :1, :6, :1, :1, :39, :3, :5, :3, :5, :194, :1, :2, :1, :1, :6, :2, :1, :1, :35, :1, :1, :48, :103, :1, :25, :226, :13205, :1, :5, :90, :2, :1, :1, :1, :19, :5, :1, :1, :1, :1, :1, :6, :8, :1, :1, :3, :3, :6 } ```
qstokkink commented 6 years ago

We can also use gc for checking where objects (including built-ins) were created:

import gc

a = list()
b = ""
c = {'a': 2}

def get_referring_files(obj):
    refs = gc.get_referrers(a)
    files = set()
    for ref in refs:
        if isinstance(ref, dict):
            for v in ref.values():
                if isinstance(v, basestring) and v != '':
                    files |= {v}
    return files

def collect_referring_files(*objs):
    return reduce(lambda a, b: (get_referring_files(b) | a), objs, set())

print collect_referring_files(a, b, c)
$ python test.py 
set(['test.py', '__main__'])
qstokkink commented 6 years ago

Related to #3598

qstokkink commented 6 years ago

Some observations:

Since I don't see a good solution, for now we will have to accept that meliae randomly segfaults some times I guess.

devos50 commented 6 years ago

I noticed that meliae does not work/is not available in the repos so I guess we have to move to another memory dumper soon.

qstokkink commented 6 years ago

I stumbled upon this: https://gist.github.com/mgeeky/6a8fa7814efb6c8ad783c3c76c791c4c . Whether or not this is fast or works at all, I do not know. Generally though, I think a dump-first-analyze-later approach would be good.

drew2a commented 3 years ago

As an option: https://pythonhosted.org/Pympler/index.html

Example of diff:

                                                      types |   # objects |   total size
=========================================================== | =========== | ============
                                                       list |          16 |     84.18 KB
                                                        str |         182 |     16.19 KB
                                     traceback.FrameSummary |         141 |      9.91 KB
                               function (trackback_wrapper) |          55 |      7.30 KB
                                     traceback.StackSummary |          55 |      4.71 KB
                                                      tuple |          82 |      4.46 KB
                                                       cell |         110 |      4.30 KB
  tribler_gui.tribler_request_manager.TriblerNetworkRequest |          31 |      4.12 KB
                                                     method |          52 |      3.25 KB
                                    PyQt5.QtWidgets.QAction |          17 |      2.26 KB
                                                       code |           3 |      1.87 KB
                                                      float |          56 |      1.31 KB
                                                        int |          45 |      1.23 KB
                                    PyQt5.QtWidgets.QWidget |           6 |    816     B
                                     PyQt5.QtWidgets.QLabel |           6 |    816     B
ichorid commented 3 years ago

related to #5203

qstokkink commented 3 months ago

Performing memory dumps is not (/no longer) part of Tribler's core functionality. I consider this out of scope and I'll close this issue.