#!/usr/bin/python3 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- # # This file is part of the LibreOffice project. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # ### script to help debug leaks of reference counted objects ## I. to use it, first override acquire() and release() # Foo * g_pTrackedFoo = 0; # Foo::Foo() # static int nFoos = 0; # if (++nFoos == 42) // track instance #42 # g_pTrackedFoo = this; # void Foo::acquire() # if (this == g_pTrackedFoo) # ; // set gdb breakpoint here # Foo_Base::acquire() # void Foo::release() # if (this == g_pTrackedFoo) # ; // set gdb breakpoint here # Foo_Base::release() ## II. run test/soffice in gdb and set breakpoints in acquire/release ## with a command to print the backtrace # set logging on # break foo.cxx:123 # break foo.cxx:234 # command 1 2 # bt # c # end # run ## III. now feed logfile gdb.txt into this script # bin/refcount_leak.py < gdb.txt ### from operator import itemgetter import re import sys threshold = 2 class Trace: clock = 0 # global counter # frames: list of stack frames, beginning with outermost def __init__(self, lines): lines.reverse() self.frames = lines Trace.clock += 1 self.clock = Trace.clock def addTrace(traces, lines): if not(traces is None) and len(lines) > 0: traces.append(Trace(lines)) def readGdbLog(infile): traces_acquire = [] traces_release = [] current = None lines = [] apattern = re.compile("^Breakpoint.*::acquire") rpattern = re.compile("^Breakpoint.*::release") for line in infile: if apattern.match(line): addTrace(current, lines) lines = [] current = traces_acquire if rpattern.match(line): addTrace(current, lines) lines = [] current = traces_release if line.startswith("#"): # strip #123 stack frame number, and newline lines.append(line[line.index("0x"):-1]) addTrace(current, lines) print("# parsed traces acquire: ", len(traces_acquire)) print("# parsed traces release: ", len(traces_release)) return (traces_acquire, traces_release) def getFunction(frame): start = frame.index(" in ") + len(" in ") try: end = frame.index(" at ", start) except ValueError as e: # argh... stack frames may be split across multiple lines if # a parameter has a fancy pretty printer return frame[start:] return frame[start:end] def matchStack(trace_acquire, trace_release): if trace_release.clock < trace_acquire.clock: return None # acquire must precede release common = 0 refpattern = re.compile(r"::Reference<.*>::Reference\(") for (frame1, frame2) in zip(trace_release.frames, trace_acquire.frames): if frame1 == frame2: common += 1 else: if getFunction(frame1) == getFunction(frame2): common += 1 acquireframes = len(trace_acquire.frames) # there is sometimes a dozen frames of UNO type related junk # on the stack where the acquire() happens, which breaks the # matching; try to avoid that for i in range(common, acquireframes): if refpattern.search(trace_acquire.frames[i]): acquireframes = i+1 # cut off junk above Reference ctor break score = max(len(trace_release.frames), acquireframes) - common # smaller score is better return (score, trace_release.clock - trace_acquire.clock) # brute force greedy n^2 matching def matchStacks(traces_acquire, traces_release): matches = [] for release in traces_release: for acquire in traces_acquire: score = matchStack(acquire, release) if score is not None: matches.append((score, acquire, release)) matches.sort(key=itemgetter(0)) return matches def bestMatches(traces_acquire, traces_release, matches): traces_aunmatched = traces_acquire traces_runmatched = traces_release bestmatches = [] for (score,acquire,release) in matches: if not(acquire in traces_aunmatched and release in traces_runmatched): continue traces_aunmatched.remove(acquire) traces_runmatched.remove(release) bestmatches.append((score,acquire,release)) print("# unmatched acquire: ", len(traces_aunmatched)) print("# unmatched release: ", len(traces_runmatched)) return (bestmatches,traces_aunmatched,traces_runmatched) def printTrace(trace): for frame in reversed(trace.frames): print(" ", frame) def printMatched(bestmatches): for (score,acquire,release) in reversed(bestmatches): print("\n*** Matched trace with score: ", score) print(" acquire: ") printTrace(acquire) print(" release: ") printTrace(release) def printUnmatched(traces, prefix): for trace in traces: print("\n*** Unmatched trace (", prefix, "):") printTrace(trace) if __name__ == "__main__": (traces_acquire, traces_release) = readGdbLog(sys.stdin) matches = matchStacks(traces_acquire, traces_release) (bestmatches,traces_au,traces_ru) = bestMatches(traces_acquire, traces_release, matches) # print output, sorted with the most suspicious stuff first: printUnmatched(traces_au, "acquire") printUnmatched(traces_ru, "release") printMatched(bestmatches) # vim:set shiftwidth=4 softtabstop=4 expandtab: re/+/108039 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Fix (some of) fallouts from tools::Long change to 64 bit on _WIN64 2020-11-13T10:16:08+00:00 Mike Kaganski mike.kaganski@collabora.com 2020-11-13T06:04:59+00:00 f2dfa6bec9895892b58e22682ecdc5865fc249a3 Change-Id: I297d43c594c5d8c3378e8b7f29ad798e89e4ebaf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105776 Tested-by: Mike Kaganski <mike.kaganski@collabora.com> Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Change-Id: I297d43c594c5d8c3378e8b7f29ad798e89e4ebaf
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105776
Tested-by: Mike Kaganski <mike.kaganski@collabora.com>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
tdf#42949 Fix IWYU warnings in include/vcl 2019-04-10T08:15:00+00:00 Gabor Kelemen kelemen.gabor2@nisz.hu 2019-04-09T21:12:06+00:00 dab764b70855c884cdd1583911b68031635c0f10 Found with bin/find-unneeded-includes Only removal proposals are dealt with here. There were some changes since last run and some omitted files Change-Id: I666ac8ed7d06684e252ca590e3d7d454e9e10975 Reviewed-on: https://gerrit.libreoffice.org/70497 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Found with bin/find-unneeded-includes
Only removal proposals are dealt with here.

There were some changes since last run and some omitted files

Change-Id: I666ac8ed7d06684e252ca590e3d7d454e9e10975
Reviewed-on: https://gerrit.libreoffice.org/70497
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Support for native 32bit Bitmap in VCL and SVP (cairo) backend 2019-04-03T09:57:08+00:00 Tomaž Vajngerl tomaz.vajngerl@collabora.co.uk 2019-02-15T12:14:32+00:00 86ea64f216819696cd86d1926aff0a138ace2baf This adds basic support for 32bit bitmaps for the SVP backend. For other backends the support is disabled for now as we need to add it for each backend separately and enable support. When this patch is applied it is possible to a Bitmap with bit count 32, but currently no input filter uses this with the exception of the new PngImageReader(libpng based), which is used only for the icons. For a general support more things need to be implemented and tested: - conversion back and fourth between 32-bit and 24-bit + 8bit alpha (or other supported pairs) - 'raw' export of the bitmap needs to be handeled properly (like in SVM import/export) so it creates the correct image. - input filters need to be checked and converted if this is necessary - look for possible bugs when drawing transparent bitmaps - check of UNO API Change-Id: I7a7be0e6134dfdd9a7aeaef897131bb6e710ae7e Reviewed-on: https://gerrit.libreoffice.org/69289 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Tested-by: Tomaž Vajngerl <quikee@gmail.com>
This adds basic support for 32bit bitmaps for the SVP backend. For 
other backends the support is disabled for now as we need to add it for 
each backend separately and enable support.

When this patch is applied it is possible to a Bitmap with bit count 
32, but currently no input filter uses this with the exception of the 
new PngImageReader(libpng based), which is used only for the icons.

For a general support more things need to be implemented and tested:
- conversion back and fourth between 32-bit and 24-bit + 8bit alpha (or 
other supported pairs) 
- 'raw' export of the bitmap needs to be handeled properly (like in
SVM import/export) so it creates the correct image.
- input filters need to be checked and converted if this is necessary
- look for possible bugs when drawing transparent bitmaps
- check of UNO API

Change-Id: I7a7be0e6134dfdd9a7aeaef897131bb6e710ae7e
Reviewed-on: https://gerrit.libreoffice.org/69289
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Tested-by: Tomaž Vajngerl <quikee@gmail.com>
add PngImageFilter that uses libpng for PNG loading 2019-02-09T10:57:48+00:00 Tomaž Vajngerl tomaz.vajngerl@collabora.co.uk 2019-02-08T20:30:39+00:00 34a6e8443312c5f9aa0a1bb055fac50d722a90ff This adds loading of PNG images that uses libpng instead of our own solution. It always loaded the image as either RGB or RGBA image and if the source PNG is using something else, libpng converts to either RGB or RGBA. In addition this adds tests for loading of various PNG files to make sure the resulting bitmaps are using pixel data as expected. (especially needed to check the RGBA bitmaps) Change-Id: I194321caf76c2ec2365bb6075c79c5e84983658a Reviewed-on: https://gerrit.libreoffice.org/67571 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This adds loading of PNG images that uses libpng instead of our
own solution. It always loaded the image as either RGB or RGBA
image and if the source PNG is using something else, libpng
converts to either RGB or RGBA.

In addition this adds tests for loading of various PNG files to
make sure the resulting bitmaps are using pixel data as expected.
(especially needed to check the RGBA bitmaps)

Change-Id: I194321caf76c2ec2365bb6075c79c5e84983658a
Reviewed-on: https://gerrit.libreoffice.org/67571
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>