English Amiga Board

English Amiga Board (https://eab.abime.net/index.php)
-   Coders. C/C++ (https://eab.abime.net/forumdisplay.php?f=118)
-   -   Memory Leak Tracing Help (https://eab.abime.net/showthread.php?t=104360)

Warty 17 October 2020 16:16

Memory Leak Tracing Help
 
I'm using VBCC and the Eclipse CDT->GCC chain for dev. Target is 3.1.14. I use MungWall, MuForce, MemMinister, and CodeWatcher.

One weird thing I can't track down is this CodeWatcher output:
Code:

The following memory blocks were NOT freed:
 Addr: $5A270 Size: 248 RtnAddr: $F8EA6E Hunk: ROM Space Ofst: None
 Addr: $3BF6F8 Size: 10 RtnAddr: $F8EA44 Hunk: ROM Space Ofst: None
 Addr: $2C250 Size: 248 RtnAddr: $F8E9AC Hunk: ROM Space Ofst: None
 Addr: $36B038 Size: 10 RtnAddr: $F8E986 Hunk: ROM Space Ofst: None

This happens in all the apps I write (ok, that's a small number! :). I can trim down an app to just the OpenScreen, and it happens. No open screen, it doesn't happen. I'm doing CloseScreen at the end of course. If I run an app 4 times in a row, it often (but not always) uses the same 4 RAM addresses, which seems odd to me if they really weren't being freed.

Is this something I should even be worrying about? Are these maybe being harvested back by the OS at some point after CodeWatcher exits? If this is not "normal", any advice on how to track it down? I've looked at the memory, but I can't tell what it is. I mean, the 10s are pointers to the 248s, but I can't make out what the 248 blocks are.

Code:

        if ( (global_app->screen_ = OpenScreenTags(NULL,
                        SA_Depth,        the_depth,
                        SA_LikeWorkbench, TRUE,
                        SA_Interleaved,  TRUE,
                        SA_Title,        the_title,
                        TAG_DONE)) == NULL)


Samurai_Crow 17 October 2020 16:20

What OS version are you using? OS3.0 had problems with the memory system allocator.

Warty 17 October 2020 16:59

Have been developing against 3.1.4.

I ran it just now against 3.1 (KS 40), and similar result in code watcher, but the 248 byte items are 292.

Thomas Richter 17 October 2020 17:49

Quote:

Originally Posted by Warty (Post 1435178)
I'm using VBCC and the Eclipse CDT->GCC chain for dev. Target is 3.1.14. I use MungWall, MuForce, MemMinister, and CodeWatcher.

Please do not use MungWall any more. This program has a workaround for a layers.library issue that is no longer existing, and just creates problems on any kickstart more modern than 3.0. Replace by Wipeout or by MuGA.

Warty 17 October 2020 18:43

Thanks for that info Thomas. I replaced mungwall with MuGuardianAngel (http://aminet.net/package/dev/debug/MuGuardianAngl.lha).

Warty 07 December 2020 06:25

I finally worked up a minimal testbed for this, because it was bugging me, but I don't know what the results mean.

Test program: all it does is open a window (on a custom screen, or not). you close the window, the program exits

First of all, the test results:

If I DO open a custom screen, I get these memory leaks:
Code:

The following memory blocks were NOT freed:
 Addr: $54280  Size: 248  RtnAddr: $F8EA6E  Hunk: ROM Space  Ofst: None
 Addr: $42ED40  Size: 10  RtnAddr: $F8EA44  Hunk: ROM Space  Ofst: None
 Addr: $54110  Size: 248  RtnAddr: $F8E9AC  Hunk: ROM Space  Ofst: None
 Addr: $3F4960  Size: 10  RtnAddr: $F8E986  Hunk: ROM Space  Ofst: None

If I do NOT open a custom screen, I get the following memory leaks reported:
Code:

The following memory blocks were NOT freed:
 Addr: $3A9600  Size: 40  RtnAddr: $FB4C46  Hunk: ROM Space  Ofst: None
 Addr: $3EE830  Size: 40  RtnAddr: $FB4C46  Hunk: ROM Space  Ofst: None
 Addr: $3ECDE0  Size: 40  RtnAddr: $FB4C46  Hunk: ROM Space  Ofst: None

If I do NOT open a custom screen, and remove the WA_SizeGadget, the leak goes down to this::
Code:

The following memory blocks were NOT freed:
 Addr: $42AB60  Size: 40  RtnAddr: $FB4C46  Hunk: ROM Space  Ofst: None

If I do NOT open a custom screen, keep the WA_SizeGadget, but remove the Mouse Move IDCMP tag, the leak is:
Code:

The following memory blocks were NOT freed:
 Addr: $42EB50  Size: 40  RtnAddr: $FB4C46  Hunk: ROM Space  Ofst: None

If I do NOT open a custom screen, and further remove the window open tag for WA_SizeGadget, and the tag for ICDMP mouse move, the memory leaks disappear:
Code:

All allocated memory was freed.
Why is there a memory leak from opening the screen? Why, if I comment out the open screen code, do I get those little leaks around the resize gadget and/or mousemove?

I get same leaks when compiling with Bebbo gcc toolchain, as with VBCC. I don't have a native Amiga C compiler, so haven't tested that.

here's the test program:
Code:

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <clib/intuition_protos.h>
#include <clib/exec_protos.h>
#include <pragmas/intuition_pragmas.h>

#define MINVERSION  40

#define BOOL    unsigned char
#define ULONG    unsigned long
#define WORD    short
#define UWORD        unsigned short

struct Library        *IntuitionBase;

/******************/


int main(void)
{
        struct Screen        *screen;
        struct Window        *window;
        struct IntuiMessage  *intuiMsg;
        BOOL                  quit;
        WORD                  i;

    if (IntuitionBase      = OpenLibrary("intuition.library", MINVERSION))
    {
        if (screen = OpenScreenTags(NULL,
                        SA_Depth,        4,
                        SA_LikeWorkbench, TRUE,
                        SA_Title,        "Leak Test",
                        TAG_DONE))
        {
                        if (window = OpenWindowTags(NULL,
                                WA_Height,      200,
                                WA_Width,        400,
                                WA_CustomScreen, screen,
                                WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MOUSEMOVE,
                                WA_SizeGadget,  TRUE,
                                WA_DragBar,      TRUE,
                                WA_CloseGadget,  TRUE,
                                WA_Activate,    TRUE,
                                TAG_DONE))
                        {
                                quit = FALSE;
                                while (!quit)
                                {
                                        WaitPort(window->UserPort);
                                        intuiMsg = (struct IntuiMessage *)GetMsg(window->UserPort);

                                        switch (intuiMsg->Class)
                                        {
                                                case IDCMP_CLOSEWINDOW: quit = TRUE;
                                                                                                break;

                                        }

                                        ReplyMsg((struct Message *)intuiMsg);
                                }

                                CloseWindow(window);
                        }

            CloseScreen(screen);
        }

        CloseLibrary(IntuitionBase);
    }

    return 0;
}


alkis 07 December 2020 07:19

Could this be a false positive on the reporting tools?

I compiled and run your code. Avail reports the same memory free before and after executing your code. No leak.

PS: On standard emulated A1200 (if that matters)

patrik 07 December 2020 08:08

You should not need to #define types. Including exec/types.h should be enough.

tygre 01 February 2021 15:28

Hi!

You could also use fortify, it's great at reporting unfreed memory, overwrites, etc.

Cheers!

bebbo 01 February 2021 16:52

Quick guess:
Your "phantom memory loss" is related to your console history/buffer.

EDIT:

more time to write now:

I can run that example program over and over and the memory reported by `avail` stays constant, but only if I disable the history stuff in KingCon...

Thomas Richter 01 February 2021 20:18

To detect memory leaks, first run SegTracker to be able to find out in which segment/resident module the allocation is located. Then, try something like MemLog (in aminet) which will record all memory allocations. There is a short usage guide included.

edmayn 18 February 2021 22:31

I have diving into this the last couple of days, since after having added a simple window, with no IDCMP flags, to a program I am currently developing MemLog started reporting a memory leak, like this:

Code:

0x00000028 bytes at 0x07DDD4C8, Stack traceback:
        0x07930E70 0x078083E0 0x00000028 0x07930EB8 0x07EB9A82 0x07931CD8 0x07F1AE00 0x07811090
        0x07931CA2 0x078D1DB8 0x07930D5C 0x07F1B0F0 0x07811090 0x078D1DB8 0x07930DD2 0x00000000
        0x078D1DB8 0x07DEB1B8 0x01F7078D 0x1DB80000 0x078D1DB8 0x07DEB1B8 0x078D1DB8 0x07EB99A0
        0x07930A46 0x00000000 0x07E220B4 0x07DEB1B8 0x078083E0 0x07E6C8B0 0x07EB99B0 0x07930910
        0x0780A12C 0x078D1DB8 0x07EB99E0 0x07916162 0x01F7843B 0x00000000 0x07E220B4 0x0780A12C
        0x07EB9B10 0x07EB9A88 0x078083E0 0x00000000 0x07DEB1B8 0x078083E0 0x00FE6FD4 0x0780A12C
        0x00FD62AC 0x00000000 0x07DEB1B8 0x00FD53B0 0x07E220B4 0x07E220B4 0x0780A12C 0x00FD60E8
        0x07EB9B10 0x00FD69D2 0x0000000E 0x07E220B4 0x07EB9A4C 0x0780A12C 0x00FD5074 0x00FD4F94
0x00009BAF bytes required in total, 0x00000028 not yet released.

The window is closed with "CloseWindow()".

CodeWatcher reports something similar.

This simple piece of code, also triggers a warning:
Code:

#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/dos.h>

int main(void)
{
        struct TagItem tagitem[8];
        struct Window *window;
        unsigned long ilock = LockIBase(0L);
        struct Screen *screen = LockPubScreen(NULL);

        tagitem[0].ti_Tag = WA_Width;
        tagitem[0].ti_Data = 500;
        tagitem[1].ti_Tag = WA_Height;
        tagitem[1].ti_Data = 300;
        tagitem[2].ti_Tag = WA_Top;
        tagitem[2].ti_Data = 400;
        tagitem[3].ti_Tag = WA_Left;
        tagitem[3].ti_Data = 300;
        tagitem[4].ti_Tag = WA_Borderless;
        tagitem[4].ti_Data = 1;
        tagitem[5].ti_Tag = WA_NoCareRefresh;
        tagitem[5].ti_Data = 1;
        tagitem[6].ti_Tag = WA_IDCMP;
        tagitem[6].ti_Data = 0;
        tagitem[7].ti_Tag = TAG_DONE;

        if (!(window = OpenWindowTagList(NULL, tagitem))) {
                UnlockPubScreen(NULL, screen);
                UnlockIBase(ilock);
                return 1;
        }

        UnlockPubScreen(NULL, screen);
        UnlockIBase(ilock);

        Delay(200);
        CloseWindow(window);
       
        return 0;
}

I also tried the above code with OpenLibrary/CloseLibrary with Intuition.library. NULLing the window->RastPort, reply to UserPort msgs (even though it should not be needed with no IDCMP flags and NOCAREREFRESH + Borderless.

To check if it may be a false positive, I checked Intellifont and IconEdit with MemLog and MemLog also reported leaks for those.

So, perhaps opening a window on the Workbench screen trigger false positives, as in opening a window always leaks? Perhaps this is documented somewhere.

I am also using 3.1.4 and compiling code with m68k-amigaos-gcc (GCC) 6.5.0b 201226214530 (thank you Bebbo!!)

edmayn 19 February 2021 10:02

A pattern I noticed.

MemLog does not report mem leak for my application if I launch it from the info file and open a new shell window to Avail Flush after termination.

This also works:

1. Open three shell windows.
2. In the first window run Avail Flush and then MemLog TASKNAME <name of task>
3. In the second window run <task name>
4. When the task stops in the second window close it.
5. Run Avail Flush in the third window and then close it.
6. CTRL-C MemLog.

This is not needed if my application does not open a window.

Thomas Richter 19 February 2021 10:41

Note that the task name is the program name as you start it on the shell, case sensitive, potentially with the full path upfront. Thus, if you start your program as "Foo:Bar/bla", the TASKNAME should be exactly that.
If you start a program from workbench, the task name is the name of the icon, case-sensitive.

edmayn 19 February 2021 11:14

@Thomas Richter
Ah, devil is in the details (as always).

Indeed specifying the exact path solves the problem.

Thanks.

(Lol that was a timesink)


All times are GMT +2. The time now is 17:00.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.

Page generated in 0.04699 seconds with 11 queries