Solved

simple image processing bug - freeing malloc'ed memory causes int 03 crash

Posted on 2003-11-08
15
357 Views
Last Modified: 2013-11-18
I am writing a plugin for a low level video editing application I've developed. The plugin takes numerous information parameters from the application and displays a brightness/contrast dialog with a preview of what it will look like. The dialog has two sliders for controlling the brightness and contrast individually. When you accept the dialog, the same algorithm used on the preview is applied to the whole frame in the animation.

the full plugin source code for vc++6.0 or higher (compiled with .net) is at the bottom of the page (link). A beta of the application is also provided so you can test the plugin in the \plugins\ directory

The problem is really in FilterFrame() where it allocated the preview frame memory then calls PropertiesOK() then unallocates it. If I dont call PropertiesOK then it works (i think) but if I do and it shows the dialog, the pointer is getting corrupted somehow maybe, even though it is exactly the same value before and after and the data looks fine.

You may see something striaght away ive misse dor it may take a while to debug, im not really sure. Please keep me up to date with comments of any questions/queries you may have and I will answer them without delay.

http://www.pcsoftware.co.nz/av3pluginproblem.zip
to test the plugin code you can go frames->import frame in av3 and then make sure brightness/contrast is selected on the adjust panel to the right, and just click apply now. you should then see the dialog

Thanks for your time,
Ryan

note: im reasonably new to this website
0
Comment
Question by:vbgenius
  • 5
  • 4
  • 3
  • +2
15 Comments
 
LVL 6

Expert Comment

by:Mafalda
Comment Utility
I got the following warnings when building the project:

Linking...
LINK : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/INCREMENTAL:NO' specification
   Creating library .\Debug/plugin.lib and object .\Debug/plugin.exp
plugin.exp : warning LNK4070: /OUT:AV3.dll directive in .EXP differs from output filename 'C:\Documents and Settings\Ryan O'Connor\Desktop\AV3\Debug\Plugins\testplugin.dll'; ignoring directive
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
You are most likely trying to free memory that was allocated in a different module. If so, make sure that both the app and the DLL use msvcrt.dll (go to the project settings, C++, Code Generation and set "Use runtime library" to "multithreaded DLL")
0
 

Author Comment

by:vbgenius
Comment Utility
Hi jkr,
I'm not entirely sure what this does but I set the app and dll to "multithreaded DLL" and I dont think it made any difference. At least it still crashes the same when it reaches free()
:-( you might have something though because someone mentioned allocating and freeing memory in diff modules in a chat room to me, but I am allocating and freeing in the same function as you should be able to see from the code. Maybe is it because the dialog box is being called with the hwnd of the parent app?
0
 

Author Comment

by:vbgenius
Comment Utility
Points increased to 400. This is now an urgent question, please any comments from people who know what they're doing are wanted. I need communication here...
0
 
LVL 6

Expert Comment

by:Mafalda
Comment Utility
Hi vbgenius,

First, my previous comment was merely an observation ...

Also, Not calling PropertiesOK() doesn't solve the memory problem !

Your problem is, on my honest opinion, releasing the memory of previewImg


free(previewImg);  <<<<<---- This line !
SelectObject(picHDC, oldnewBmp);
DeleteObject(newBmp);
DeleteObject(oldnewBmp);
DeleteDC(picHDC);

You use a char * and pass it as a non const to GetDIBits and as a const void * to other functions

GetDIBits(picHDC, newBmp, 0, 68, previewImg, &bmi, DIB_RGB_COLORS);

I think that the pointer is manipulated (I think in GetDIBits) and thus when you try to free the memory you fail.

Also you might try to realloc memory instead of allocating a new portion each time (if possible)

Try passing a different (temporary) buffer's pointer to GetDIBits and copying the memory later (memcpy)

If possible track the value of previewImg. You will probably see that it changes ...

BTW I found many other nonfunctioning things (limitting myself to changing the B/C of a one frame and a range of frames) ;o)

Tell us your opinion.
0
 

Author Comment

by:vbgenius
Comment Utility
Hi Mafalda thanks a lot for your comment again, however still not luck:


Your problem is, on my honest opinion, releasing the memory of previewImg
free(previewImg);  <<<<<---- This line !

- I have already discovered this is what makes it crash, but without it the application will not run the FilterFrame function twice and the app may crash on exit, etc. It needs to be fixed! somehow... I'm getting there it must be something to do with memory modules or something that im not too flash on, I know we can solve this!!


Also, Not calling PropertiesOK() doesn't solve the memory problem !

- according to my observation it does... the dialog is not shown and the frame results in a dark grey colour instantly. You can run the plugin as many times as you want and it wont crash.


I think that the pointer is manipulated (I think in GetDIBits) and thus when you try to free the memory you fail.

- Commenting out GetDIBits and StretchDIBits has no effect so this cant be the problem, and the pointer has the same value during the time between malloc and free


Also you might try to realloc memory instead of allocating a new portion each time (if possible)

- not possible because if the user does not choose this plugin during the run time of the program (very likely), it will just waste space which the program desperately needs, and due to the nature of dlls (in DllMain) I dont think it would be easily done anyway.


Try passing a different (temporary) buffer's pointer to GetDIBits and copying the memory later (memcpy)

- I have not tried this yet because I'm positive GetDIBits is not the problem, commenting it out sitll crashes (above)


If possible track the value of previewImg. You will probably see that it changes ...

- I have; it does not change from when I allocate it to when it has a "user breakpoint" after returning from the dialog procedure and checking the esp register.


BTW I found many other nonfunctioning things (limitting myself to changing the B/C of a one frame and a range of frames) ;o)

- yes, it is unfinished I need to get this memory allocation fixed to code the rest of it. I also left it unfinished so there was less code for you to look over
0
 
LVL 1

Expert Comment

by:bearcrsw
Comment Utility

I haven't managed to get this to link I get the following error.

dllcode.obj : error LNK2001: unresolved external symbol __imp__InitCommonControls@0

but from looking at your code, I think the problem is that when the PropertiesOk returns you free the memory,

but a draw request is also sent, as the dialog obscured the window.

so when UpdatePreview(...) is called the memory for previewImg has already been freed.

I would suggest setting previewImg to NULL after the free and then testing the value of previewImg before use in UpdatePreview....

Steve

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:vbgenius
Comment Utility
Hi Steve,

Thanks for your reply. I think the error you are recieving means for some reason your linker is not including comctl32.lib when the program compiles, check this file is included in additional dependencies of the linker input in project properties (vc7).

I am freeing the memory after the function PropertiesOK returns:

      //show properties dialog
      ret = PropertiesOK(AV3Hwnd);

      //cleanup preview stuff
      free(previewImg);

Right now I am getting a user breakpoint while in debug mode on this line inside the PropertiesOK function:

      int ret = DialogBox((HINSTANCE)moduleDll, (LPCTSTR)IDD_PROPS, parentHwnd, (DLGPROC)PropertiesProc);


I think is problem is virtually impossible to solve unless you are compiling the project and testing... so please give it another go!

I added a check to see if previewImg is null like you said and set it to NULL after it was freed, but it does not even reach the line where the memory is freed!!! because it does not fully exit out of the dialog.

******* Important: If you continue from the breakpoint or run the exe instead of debug, the application seems to resume functioning normally until you run the plugin again. If in debug, malloc() simply returns NULL, if in the exe - the application tries to write to 0x80808080 and causes an exception.

I'm starting to think the problem may be more that the memory is getting truncated somehow...
0
 
LVL 6

Expert Comment

by:Mafalda
Comment Utility
--Also, Not calling PropertiesOK() doesn't solve the memory problem !

--- according to my observation it does... the dialog is not shown and the frame results in a dark grey colour instantly. You can run the plugin as many times as you want and it wont crash.

In my case it didn't matter and the behaviour was similar.
If it does behave differently on two machines it shows that it is a memory problem like memory interlacing that corrupts other variable's values.

Different behaviour between runtime and debug also shows a memory problem which behaves diferently because of the intervention of the debugger specially when the debugger is run.

Please check that the amount of memory used might exceed the one allocated.
Also check that it size doesn't varies while the program runs.

Mafalda
0
 
LVL 6

Expert Comment

by:Mafalda
Comment Utility
sorry ...
"intervention of the debugger" - should read "intervention of the debug libraries"
0
 
LVL 1

Accepted Solution

by:
bearcrsw earned 400 total points
Comment Utility
Okay managed to get this working now,

and looking at the previewImg data buffer I can see when GetDIBits is called the memory past the end of the buffer is changed.

So looking at the data in the buffer a bit more carefully it appears that each line of the bitmap data is padded to be on a 32byte boundary,

ie for image line length 102. so end of line in buffer is 306

img[305] = img end line 1
img[306] = pad
img[307] = pad
img[308] = img line 2

As the image size you have chosen is not a multiple of 32 the buffer needs to be longer, or the image size needs to be changed to be a multiple of 32.

This can be seen in the preview image, the right hand side of the top line never changes, as this is past where you modify the values, and off the end of the array.

A few other points, the previewImg is malloc'ed  twice, so the first buffer is lost. No tidying up of previewImg and other buffers is done if the filter is cancelled.

0
 

Author Comment

by:vbgenius
Comment Utility
YES! finally.. thank you sir that indeed was the problem.. I cant believe I didnt see that 102 does not divide by 4. I was more concerned at the start that of the ratio 102:68 is 3:2... oh well glad i finally got that one out of that way, a well deserved 400 points, also thanks to mafalda as I believe this was a combined effort!

also bearcrsw may I ask for your name please, as I would like to add you to the credits of our application. If you are not willing that is fine, thank you!
0
 
LVL 1

Expert Comment

by:bearcrsw
Comment Utility
Of course, I have just updated my profile so you can see that.

Steve Bearcroft
0
 
LVL 9

Expert Comment

by:tinchos
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: bearcrsw {http:#9804467}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now