ssbssa / heob

Detects buffer overruns and memory leaks.
Boost Software License 1.0
156 stars 25 forks source link

command line option sequence issue #32

Closed asmwarrior closed 2 months ago

asmwarrior commented 2 months ago

Hi, it looks like the option should be put before the debugee name.

For example

heob64 bin/Debug/MathPlotDemo.exe -F1 >> aaa.txt

In the above command, the option -F1 does not take effect. But the below command works:

heob64 -F1 bin/Debug/MathPlotDemo.exe  >> aaa.txt

Is this by design?

Thanks.

ssbssa commented 2 months ago

Yes, that's intentional.

The help text says: Usage: $\textcolor{#00ff00}{\textbf{heob64}}$ $\color{#ff00ff}{\textbf{[OPTION]...}}$ $\color{#00ffff}{\textbf{APP [APP-OPTION]...}}$

So any arguments after the target executable name are the arguments for the target executable.

PS: If you like colors, try as output file something like: > aaa.html

asmwarrior commented 2 months ago

Thanks for the clarification.

Oh, yes, I like colors, so direct to the html is a better method.

This tool has so many options that I really don't know all its usage. Thanks.

asmwarrior commented 2 months ago

I think I will close this issue. (question)

I still hope that there are some tutorials which can teach me how to use this tool, especially the difference between each options.

ssbssa commented 2 months ago

Depends on what you want to do, here some examples:

Check for heap-overflows and use-after-free errors (needs lots of memory):

heob64 -f1 -l0 -F1 SOME-APP

Check for memory leaks:

heob64 -vleaks.svg -p0 SOME-APP

Use as a profiler:

heob64 -vprofiler.svg -I100 SOME-APP

Simple analysis of minidump file:

heob64 -D15 -F1 SOME-CRASH.dmp

One thing that I've often found useful for either leak-checking or profiling is the -k1 argument. With it you can control leak recording (and if you're in profiling mode, it controls profiling). So you can enable and disable it interactively in the console where heob is running, and it only outputs the leaks or profiling-samples from the time it was enabled. Most useful when working with a GUI program, so you enable it before the interesting part starts, and disable it when it is finished.

heob64 -vleaks.svg -p0 -k1 SOME-APP

Full help text:

heob64 -HH
asmwarrior commented 2 months ago

Thanks for your help.

I think it is the time to let me start a new memory leak detect plugin inside Code::Blocks.

Code::Blocks already has a plugin named "Valgrind plugin", see some image here: How to use valgrind in code::blocks?

But Valgrind plugin only works under Linux.

Under Windows, I think I need heob. This tool is also embeded in QTCreator, see here: Profiling and Memory Checking Tools - Qt Wiki

and Heob | Qt Creator Documentation

EDIT: I create one post in Code::Blocks forum: memory detecting tool embeded in Code::Blocks for Windows, create a new plugin?

asmwarrior commented 2 months ago

When hunting a memory leak issue inside a wxWidgets application, I use heob to generate a color html log file.

It looks like the log file is quite huge, and can you tell me which are the actual bugs?

It contains something like:

leaks:
  264.0 KiB (#9797) '1 [12424]'
                           [malloc]
    0x000007FEDDD60000   libstdc++-6.dll
      0x000007FEDDE9229B   [operator new(unsigned long long)]
    0x000007FED8640000   wxbase32u_gcc_custom.dll
      0x000007FED880E1AB   [wxString::iterator::operator!=(wxString::const_iterator const&) const]
      0x000007FED86C7898   [wxUILocale::InitLanguagesDB()]
      0x000007FED874F3E5   [wxUILocale::FindLanguageInfo(wxLocaleIdent const&)]
      0x000007FED874F7C7   [wxUILocale::GetLayoutDirection() const]
    0x000007FED7220000   wxmsw32u_core_gcc_custom.dll
      0x000007FED722E1FD   [wxApp::MSWGetDefaultLayout(wxWindow*)]
      0x000007FED72D59B1   [wxTopLevelWindowMSW::CreateFrame(wxString const&, wxPoint const&, wxSize const&)]
      0x000007FED72DB565   [wxTopLevelWindowMSW::Create(wxWindow*, int, wxString const&, wxPoint const&, wxSize const&, long, wxString const&)]
      0x000007FED73655D8   [wxFrame::Create(wxWindow*, int, wxString const&, wxPoint const&, wxSize const&, long, wxString const&)]
    0x000000013F340000   MathPlotDemo.exe
      0x000000013F3769FF   MathPlotDemoMain.cpp:81:11 [MathPlotDemoFrame::MathPlotDemoFrame(wxWindow*, int)]
      0x000000013F37670E   MathPlotDemoApp.cpp:26:56 [MathPlotDemoApp::OnInit()]
      0x000000013F384574   app.h:93:46 [wxAppConsoleBase::CallOnInit()]
    0x000007FED8640000   wxbase32u_gcc_custom.dll
      0x000007FED86C0901   [wxInitialize(int&, char**)]
    0x000000013F340000   MathPlotDemo.exe
      0x000000013F376639   MathPlotDemoApp.cpp:17:1 [WinMain]
      0x000000013F3412ED   crtexe.c:267:15 [__tmainCRTStartup]
      0x000000013F3413E5   crtexe.c:157:9 [WinMainCRTStartup]
...

Do they mean that all the issues were inside the wxWidget library? I use wxWidgets libraries from msys2, and installed by pacman command.

What does this line:

264.0 KiB (#9797) '1 [12424]'

mean? 12424 is the thread id? #9797 is a number for this memory leak? What does 1 mean?

I have upload the html files in a zip file in this issue: Bug: Demo leaks memory · Issue #46 · GitHubLionel/wxMathPlot. Especially in this comment: https://github.com/GitHubLionel/wxMathPlot/issues/46#issuecomment-2314142878

Thanks.

ssbssa commented 2 months ago

Do they mean that all the issues were inside the wxWidget library? I use wxWidgets libraries from msys2, and installed by pacman command.

There are many entries that contain wxUILocale::InitLanguagesDB() or wxModule::RegisterModules() in the stacktrace, so I suspect that most of these leaks are just allocations that wxWidgets needs to do one time for initialization, and just never bothers to free again.

There is an option where heob tries to identify those kind of leaks, by checking if anything in the global variable or stack points to them:

    -lX    show leak details [1]
              0 = none
              1 = simple
              2 = detect leak types
              3 = detect leak types (show reachable)
              4 = fuzzy detect leak types
              5 = fuzzy detect leak types (show reachable)

Taken from the QtCreator heob docu:

Select Simple to write all memory that was not freed into the results file.

Select Detect Leak Types to parse all static and global memory blocks for references to the leaks. The reachable blocks are marked reachable and recursively checked for other references. If references are found, the blocks are marked indirectly reachable. The remaining blocks are checked for references to each other and marked either indirectly lost or jointly lost (if the blocks reference each other). The blocks that have no references at all are marked lost. Select Detect Leak Types (Show Reachable) to also record the the reachable blocks in the results file.

Select Fuzzy Detect Leak Types to mark memory blocks reachable or indirectly lost if they have references to any address. This option is useful when used with some custom allocators (such as av_malloc() in ffmpeg) that keep only an address somewhere inside the allocation block and do not refer directly to the start of an allocated block. Select Detect Leak Types (Show Reachable) to also record the reachable blocks in the results file.

But if you want to be sure if they are a problem, you will need the debug info for wxWidgets for proper source/line numbers, and inspect their source.

Note that I vastly prefer the SVG output (instead of the text/html variant) for memory leaks and profiling. That's why I wrote the option -vleaks.svg in my examples earlier. Maybe you could post it as well.

What does this line:

264.0 KiB (#9797) '1 [12424]'

mean? 12424 is the thread id? #9797 is a number for this memory leak? What does 1 mean?

Yes, 12424 is the thread id, #9797 is the allocation number, and 1 is the thread number.

Note that both html files have the same summary at the end:

  sum: 327.6 KiB / 803

Which means there are in sum 803 leaks, and together they need 327.6 KiB. So mPlot->DelAllLayers(true, false); didn't change anything at all.

In a quick look through the html I saw one suspicious entry:

  496 B (#17026) '1 [12424]'
                           [malloc]
    0x000007FEDDD60000   libstdc++-6.dll
      0x000007FEDDE9229B   [operator new(unsigned long long)]
    0x000000013F340000   MathPlotDemo.exe
      0x000000013F376A75   MathPlotDemoMain.cpp:83:87 [MathPlotDemoFrame::MathPlotDemoFrame(wxWindow*, int)]
      0x000000013F37670E   MathPlotDemoApp.cpp:26:56 [MathPlotDemoApp::OnInit()]
      0x000000013F384574   app.h:93:46 [wxAppConsoleBase::CallOnInit()]
    0x000007FED8640000   wxbase32u_gcc_custom.dll
      0x000007FED86C0901   [wxInitialize(int&, char**)]
    0x000000013F340000   MathPlotDemo.exe
      0x000000013F376639   MathPlotDemoApp.cpp:17:1 [WinMain]
      0x000000013F3412ED   crtexe.c:267:15 [__tmainCRTStartup]
      0x000000013F3413E5   crtexe.c:157:9 [WinMainCRTStartup]

What's allocation on MathPlotDemoMain.cpp:83?

And I wonder how you exit the program, maybe you could share the source code as well?

ssbssa commented 2 months ago

And I wonder how you exit the program, maybe you could share the source code as well?

Nevermind, I found it here: https://github.com/GitHubLionel/wxMathPlot/tree/master/MathPlotDemo

ssbssa commented 2 months ago

It looks like Frame from here is never deleted, is that intentional? I wonder what the heob result would look like if you add delete Frame at the end there.

asmwarrior commented 2 months ago

And I wonder how you exit the program, maybe you could share the source code as well?

Nevermind, I found it here: https://github.com/GitHubLionel/wxMathPlot/tree/master/MathPlotDemo

Oh, yes, they are in that folder. The line 83 is that

https://github.com/GitHubLionel/wxMathPlot/blob/9f9bedee2c55bdd758cac306f3ed98d758bdc0e7/MathPlotDemo/MathPlotDemoMain.cpp#L83C5-L83C89

The wxWidgets' wxAuiManager instance is created.

asmwarrior commented 2 months ago

It looks like Frame from here is never deleted, is that intentional? I wonder what the heob result would look like if you add delete Frame at the end there.

The wxWidgets' window(all wx window types) is quite special, they will be deleted automatically by the GUI framework. See here.

wxWidgets: Window Deletion

So, it is safe that you see a lot of new statement of the wxWidgets' GUI window, and you don't see the associated delete statement.

ssbssa commented 2 months ago

So, it is safe that you see a lot of new statement of the wxWidgets' GUI window, and you don't see the associated delete statement.

Well, it doesn't look like this Frame is deleted, so maybe there is something missing here for it to work? Same for the wxAuiManager instance.

Edit: Actually I misread, it looks like Frame is deleted after all. But I'm pretty sure the wxAuiManager instance is never deleted.

asmwarrior commented 2 months ago

So, it is safe that you see a lot of new statement of the wxWidgets' GUI window, and you don't see the associated delete statement.

Well, it doesn't look like this Frame is deleted, so maybe there is something missing here for it to work? Same for the wxAuiManager instance.

Edit: Actually I misread, it looks like Frame is deleted after all. But I'm pretty sure the wxAuiManager instance is never deleted.

Thanks, I will check the code especially about the wxAuiManager class.

BTW: the svg file is hard to read, I open the svg file in a web browser, but I think the content does not show well. I attach the svg in the zip file.

after-svg.zip

ssbssa commented 2 months ago

Does the SVG not look like this in your browser?: leaks-svg

It's also interactive, you can zoom in and out by clicking on the various text boxes.

asmwarrior commented 2 months ago
diff --git a/MathPlotDemo/MathPlotDemoMain.cpp b/MathPlotDemo/MathPlotDemoMain.cpp
index 9384c28..f10f5ff 100644
--- a/MathPlotDemo/MathPlotDemoMain.cpp
+++ b/MathPlotDemo/MathPlotDemoMain.cpp
@@ -152,6 +152,7 @@ MathPlotDemoFrame::MathPlotDemoFrame(wxWindow* parent,wxWindowID id)

 MathPlotDemoFrame::~MathPlotDemoFrame()
 {
+    AuiManager1->UnInit();
     //(*Destroy(MathPlotDemoFrame)
     //*)
 }
@@ -417,6 +418,7 @@ void MathPlotDemoFrame::OnUserMouseAction(void *Sender, wxMouseEvent &event, boo

 void MathPlotDemoFrame::OnmiQuitSelected(wxCommandEvent &WXUNUSED(event))
 {
+  mPlot->DelAllLayers(true, false);
   Close(true);
 }

After adding the line AuiManager1->UnInit();, I see the memory error total numbers were reduced to

sum: 41.64 KiB / 547

Compared with the previous sum: 327.6 KiB / 803

See the attached "after2.html" file in after2-html.zip

But there are still a lot of memory errors I really don't know.

BTW: I'm using the wx 3.2.4-1 version from msys2 project.

From the document: https://raw.githubusercontent.com/wxWidgets/wxWidgets/v3.2.4/docs/changes.txt It is said that: (3.1.4: (released 2020-07-22))

  • Call wxAuiManager::UnInit() automatically now.

This means the wxAuiManager::UnInit() should be called automatically when the GUI frame get destroyed, but I'm not sure why I still need to call it manually in the destructor the of frame class. And by adding this function call, the memory error number get reduced.

asmwarrior commented 2 months ago

Does the SVG not look like this in your browser?: leaks-svg

It's also interactive, you can zoom in and out by clicking on the various text boxes.

Yes, the svg shows the same in my web browser as your screen shot.

ssbssa commented 2 months ago

Yes, the svg shows the same in my web browser as your screen shot.

So it should work.

The SVG is an extended Flame Graph. Try doing left-clicks (zoom) or middle-clicks (remove) on some of the text boxes.

asmwarrior commented 2 months ago

Yes, the svg shows the same in my web browser as your screen shot.

So it should work.

The SVG is an extended Flame Graph. Try doing left-clicks (zoom) or middle-clicks (remove) on some of the text boxes.

Thanks for the help. This is my first time to see such complex svg file. This operation is a bit counterintuitive, and the interaction doesn't feel very convenient. But anyway, I will try to learn it. Thanks.

ssbssa commented 2 months ago

This operation is a bit counterintuitive, and the interaction doesn't feel very convenient.

Interesting, for me it's the opposite. When I first saw a Flame Graph, I was very impressed, because for me that was just the most intuitive and convenient way to analyze memory leaks. That's why I implemented it as well.