This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Differences between C++ 'new' operator and 'malloc()' (NOT a C/C++ question)


Ryan Johnson wrote:
> On 10/07/2012 12:46 PM, Claude SIMON wrote:
>> Ryan Johnson wrote:
>>> On 05/07/2012 9:36 AM, Claude SIMON wrote:
>>>> Ryan Johnson wrote:
>>>>> On 04/07/2012 5:45 AM, Claude SIMON wrote:
>>>>>> When I compile the component with Visual C++, it works. When I
>>>>>> compile
>>>>>> the
>>>>>> component with g++... it crashes.
>>>>>>
>>>>>> With 'gdb', I found that the problem happens when calling the
>>>>>> 'malloc'
>>>>>> function (as soon as the function is called, NOT when the returned
>>>>>> allocated memory is used). When I replace the 'malloc' by a the C++
>>>>>> 'new'
>>>>>> operator, the component compiled with Cygwin g++ doesn't crash
>>>>>> anymore.
>>>>>> I thought that the C++ 'new' operator calls the 'malloc' function,
>>>>>> but
>>>>>> this seems not to be the case. As I want to use 'malloc'-like
>>>>>> functions
>>>>>> rather than the C++ 'new' operator, I wonder which functions are
>>>>>> used
>>>>>> in
>>>>>> the C++ 'new' operator to allocate memory (and naturally which
>>>>>> functions
>>>>>> are used in the C++ 'delete' operator to free the memory).
>>>>> Operator new() and malloc() are explicitly *not* interchangeable (for
>>>>> many reasons, not least of which that the Standard says so). If you
>>>>> were
>>>>> to free new'ed memory, or delete malloc'ed memory, the resulting heap
>>>>> corruption could easily manifest as a crash the next time you tried
>>>>> to
>>>>> allocate something... or it might just silently clobber data and lead
>>>>> to
>>>>> "spooky action at a distance."
>>>>>
>>>> Thank you for the answer, but I am aware of this and my problem has
>>>> nothing to do with it, nor, as stated in the subject, with having some
>>>> lacuna in C/C++ programming.
>>>>
>>>> Let's try to be a little more explicit despite my poor English.
>>>>
>>>> Let's consider a Java native component which only calls a 'malloc(1)'.
>>>> It
>>>> doesn't even test the returned value (it is usually not a good idea,
>>>> but
>>>> it doesn't matter here).
>>>>
>>>> This component :
>>>> - compiled with g++ under Linux : works,
>>>> - compiled with g++ under Mac OS : works,
>>>> - compiled with Visual C++ under Windows : works,
>>>> - compiled with g++ under Cygwin : CRASHES !
>>>>
>>>> It crashes as soon the 'malloc(1)' function is called. You don't even
>>>> have
>>>> the opportunity to test the returned value, nor to use it. It's
>>>> perhaps
>>>> a
>>>> Cygwin bug, or perhaps a JVM/JRE/JDK bug ; I don't know and I don't
>>>> bother
>>>> (but if someone will make some investigation about that, I'm ready to
>>>> help
>>>> him or her if I can).
>>>>
>>>> When you replace the 'malloc()' by the 'new' operator, then the
>>>> component
>>>> compiled with g++ under Cygwin works too.
>>>> The 'new' operator, among other things, allocates memory, as
>>>> 'malloc()'
>>>> does, but obviously it doesn't use 'malloc()' as it doesn't crash. So,
>>>> because I can't use 'malloc()' in my Java native components, and
>>>> because
>>>> I
>>>> doesn't want to use the 'new' operator, I wish to know which functions
>>>> the
>>>> 'new' operator uses to allocate memory, so I can use them in my Java
>>>> native component so they would no more crash when compiled with g++
>>>> under
>>>> Cygwin.
>>> A crash inside malloc is 99.99% likely due to a bug in user code (wild
>>> pointer, double-free, smashed stack, etc). The fact that your code
>>> doesn't crash under other circumstances does precisely *nothing* to
>>> rule
>>> out a bug in your code if bad has been observed anywhere (it just
>>> proves
>>> the platforms really are different). The buggy code may have nothing to
>>> do with malloc, other than having the bad luck of clobbering a data
>>> structure the latter needs. Even a single mix-up of new/malloc usage
>>> (perhaps due to losing track of a pointer's provenance) is also enough.
>> Indeed. The problem is... the crash happens even when there is no other
>> code which could be buggy.
> #include <stdlib.h>
> int main() { return (int) malloc(10); }
>
> Does not crash. There must be some other code which is buggy.
>

The test case I provided is EXACTLY the code your wrote above, only
applied to a Java native component (and without the 'return', which is not
needed for the test case), and it DOES crash. So ?

>> As asked in another reply to this thread, I've made a test case, which
>> can
>> be found at :
>> 	http://cvs.savannah.gnu.org/viewvc/epeios/bugs/jcmc/?root=epeios
>> There is a README file which contains some further explanations.
> If it needs to live in a CVS repo, it's not a simple test case. Those
> usually fit inline in emails (see above). Long test cases are acceptable
> if the problem can't be narrowed down further, but you'll need to make a
> substantial effort to exclude bugs in your own code before others will
> be interested to jump in. Like running a debug allocator.

As I stated in my initial post, I'm French, so perhaps I misunderstood
what you mean by a test case.
I thought that a test case is the minimal set of instructions needed to
reproduce a bug. So, since the bug occurs only in a Java native component,
I wrote a '.java' file, which loads the native component and calls the
faulty function, a '.cpp' file, which contains the source code of the
native component and implements the faulty function, and the associated
'.h' header file (actually, this one was generated by the 'javah' tool).
This 3 files represent together circa 50 lines, including the comments
generated by the 'javah' tool. I've create a dedicated directory in a CVS
repository where I put this files, so you can have a look on them only by
using your Web browser, without having to download anything. To try the
test case, you have only to download the 3 files, which is pretty simple,
I think, and additionally a 'Makefile' I wrote, which makes all the needed
compilations (after you adapt its first line). There is also a 'README'
file which explains what the content of the directory is all about.
Where am I wrong by doing this ?

>>
>>> This is all standard memory management debugging stuff that's off topic
>>> for this list. If at some point you have some evidence besides "it
>>> crashes when I run it under cygwin" *that* would be a topic for this
>>> list.
>> With the test case above, I think that it is easy to establish if the
>> problem is off or on topic.
> Great. Please do.
>

I already do this, hence the initial post.
To tell the full story, I post the initial post first on
'mingw-users@...', and I got as answer to post here. So, if someone is
kind enough to have a look on my test case, and have a suggestion where
else I should post my message, or even a solution to fix the bug, I would
be glad to know about his/her suggestion/solution.

>>
>>> My suggestion: run under the debugging malloc library of your choice
>>> and/or Valgrind and see what that turns up.
>> Should be interesting to see if a alternative 'malloc' would also crash,
>> but would not solve my problem given what I wrote above.
> Why not? Try it, you might be surprised.

If I understand well what they wrote on the 'Valgrind' Web site, it is not
available for Cygwin, nor for Windows in general. And I didn't find in the
'Cygwin' packages what tools I can use instead (I searched for 'Purify',
'Electric Fence'...)...

>>> As to your question, new() usually calls malloc under the hood (with
>>> extra bookkeeping), but five minutes with gdb will give you a
>>> definitive
>>> answer.
>>>
>> I don't manage to make 'gdb' step into a 'new' call...
> b _malloc
> r

Thanks ! But I try this, and it executes the program without stepping into
the 'new' call.

>> Beside the crash thing, all I'm interested into, is if someone here can
>> show me the implementation of the 'new' operator as used in Cygwin, or
>> give me an address where I can found the source code of this 'new'
>> implementation, or where I may ask this questions to obtain a response
>> to
>> one of this question.
> It's burned into gcc. That's why I highly doubt cygwin's code is
> directly causing the problem here.

I thought that Cygwin implements low-level memory functions, which are
used, but obviously not in the same manner, both by the 'malloc()'
functions and the 'new' operator. To verify this, I looked in the Cygwin
source repository, but I don't know enough about Cygwin and this
repository is so big that I don't know where exactly I have to go to found
the source code corresponding to the 'new' operator. So, that's why I ask
here for some help.

-- 
Claude SIMON (sc.cygwin.com@zeusw.org)




--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]