|
From: Stefano A. <san...@al...> - 2022-02-28 16:43:25
|
Hello list, I have a Qml application that leaks memory when run normally. I've reduced it to a very simple Qml app and it still leaks. And the leak is visible with pmap almost immediately. The application runs on an embedded device (armhf). When I run it with valgrind: /usr/bin/valgrind.bin --tool=memcheck --error-limit=no \ --log-file=vg-220214.log --leak-check=full \ --leak-resolution=high --show-reachable=yes ./qml-mwe3 There is no leak. I've tried running it for a solid day and pmap doesn't show any leak. If I run the same application in gdb (just letting it run). It leaks. However, if I put a break point on malloc: gdb ./qml-mwe3 (gbd) run --- some time passes --- ^C (gdb) break malloc (gdb) commands > continue > end (gdb) run Then the leak stops. No memory is freed, but it absolutely stops increasing. Can anyone offer any guesses as to what's going on? I would appreciate any ideas to debug this further. Thanks, Stef |
|
From: Floyd, P. <pj...@wa...> - 2022-02-28 17:00:52
|
On 2022-02-28 17:28, Stefano Antonelli wrote: > Hello list, > > I have a Qml application that leaks memory when run normally. I've > reduced it to a very simple Qml app and it still leaks. And the leak > is visible with pmap almost immediately. The application runs on an > embedded device (armhf). Hi Stefano I don't know much about Qml. Does this use any sort of memory manager or garbage collector? One thing that you could try is to run your application with --tool=massif and then repeat the run but add --pages-as-heap=yes. If there is a big difference in the two then it means that your application is using a memory pool not based on malloc. Use ms_print (or massif-visualizer) to see the massif profiles. A+ Paul |
|
From: Stefano A. <san...@al...> - 2022-02-28 18:01:02
|
On Mon, 2022-02-28 at 18:00 +0100, Floyd, Paul wrote: > On 2022-02-28 17:28, Stefano Antonelli wrote: > I don't know much about Qml. Does this use any sort of memory manager > or > garbage collector? Qml is built on top of javascript. There is definitely a garbage collector. > One thing that you could try is to run your application with > --tool=massif and then repeat the run but add --pages-as-heap=yes. If > there is a big difference in the two then it means that your > application > is using a memory pool not based on malloc. Use ms_print (or > massif-visualizer) to see the massif profiles. There is a huge difference. 1MB vs 90MB. Using a memory pool doesn't explain why the leak doesn't get bigger when running valgrind though does it? And thanks for the help! -Stef |
|
From: Stefano A. <san...@al...> - 2022-02-28 21:12:15
|
On Mon, 2022-02-28 at 09:45 -0800, Stefano Antonelli wrote: > On Mon, 2022-02-28 at 18:00 +0100, Floyd, Paul wrote: > > On 2022-02-28 17:28, Stefano Antonelli wrote: > > > Using a memory pool doesn't explain why the leak doesn't get bigger > when running valgrind though does it? So I think I understand the problem. QML sits on top of EGL. The EGL layer is supplied in binary form. In pmap I see a growing number of pages owned by /dev/dri/renderD129 which is a device file. crw-rw---- 1 root render 226, 129 Feb 23 15:48 /dev/dri/renderD129 When the leak occurs, the number of 4k pages owned by this render device increases. Running valgrind leak-test (or gdb with malloc breakpoint), the number of 4k pages owned by this render device _do not_ increase. I believe that QML creates "a graphic thing" from this render device and probably also deletes it, but I don't think the library controlling the render device is freeing the memory. I *think* this library (libglapi.so) is using malloc, but I don't have any source code. ldd shows me: 12: 00000000 0 FUNC GLOBAL DEFAULT UND malloc@GLIBC_2.4 (3) So something real is happening when valgrind leak-test is used that's affecting this graphics library in a good way. Can anyone explain what valgrind does? I know it replaces malloc with vg_malloc, but does anything else happen? Thanks, Stef |
|
From: Stefano A. <san...@al...> - 2022-03-01 07:09:24
|
On Mon, 2022-02-28 at 13:11 -0800, Stefano Antonelli wrote: > When the leak occurs, the number of 4k pages owned by this render > device increases. Running valgrind leak-test (or gdb with malloc > breakpoint), the number of 4k pages owned by this render device _do > not_ increase. When I run callgrind, the same behaviour happens. valgrind --tool=callgrind --instr-atstart=no ./qml-mwe3 Once the application is up and running, I use: :~# callgrind_control --instr=on 4120 PID 4120: ./qml-mwe3 sending command instrumentation on to pid 4120 OK. :~# callgrind_control -s 4120 PID 4120: ./qml-mwe3 sending command status internal to pid 4120 Number of running threads: 4, thread IDs: 1 2 3 4 Events collected: Ir Functions: 1,104 (executed 1,289, contexts 1,104) Basic blocks: 1,816 (executed 1,120,586,516, call sites 452) :~# callgrind_control --instr=off 4120 PID 4120: ./qml-mwe3 sending command instrumentation off to pid 4120 OK. After the I turn on the instrumentation, the display stops updating completely (it's running an animation). Once I turn off the instrumentation, the display resumes. I would expect the animation to run dreadfully slow, but not freeze in place for the duration of time instrumentation was on. I don't know exactly how much time this was, but if I had to guess I'd say around 10 minutes. I should also add that the processor is armhf and I noticed with callgrind I get a couple of warnings: ==4120== Callgrind, a call-graph generating cache profiler ==4120== Copyright (C) 2002-2017, and GNU GPL'd, by Josef Weidendorfer et al. ==4120== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info ==4120== Command: ./qml-mwe3 ==4120== ==4120== For interactive control, run 'callgrind_control -h'. ==4120== Warning: noted but unhandled ioctl 0x6443 with no size/direction hints. ==4120== This could cause spurious value errors to appear. ==4120== See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper. ==4120== Warning: noted but unhandled ioctl 0x4b51 with no size/direction hints. ==4120== This could cause spurious value errors to appear. ==4120== See README_MISSING_SYSCALL_OR_IOCTL for guidance on writing a proper wrapper. disInstr(thumb): unhandled instruction: 0xDEFF 0xF8DD I don't know if that's breaking things or not. Nor do I know what these IOCTLs are, but I am trying to parse README_MISSING_SYSCALL_OR_IOCTL as I go along here. -Stef |