Hi Steve
thanks for the answer

1. some test in our product (MATLAB/Simulink) crashes

2. after debugging we found out that problem is in faulty malloc optimization 

3. real code in question is much more complicated than my example, basically it 
does the following
   
   populates some structure with set of void*, every one void* is created with 
malloc

        struct S {
                double *m1;
                double *m2;
                . . . . . . 
                double *mn;
        };

        S s;
        s.m1 = (double *)malloc(sz*sizeof(double));
        s.m2 = (double *)malloc(sz*sizeof(double));
        . . . . . . 

        s.mn = (double *)malloc(sz*sizeof(double));

        return s;

   returns that structure to the caller

   later allocated memory will be filled with some calculations results

4. it’s absolutely not clear why clang decided to optimize malloc that were 
participated in the allocation of the structure members

   even more interesting we don’t use malloc directly we use some external not 
inlined utility function that calls malloc

5. code is absolutely the same for Windows and for linux

6. test expects allocation memory failure

7. windows and linux test is passing, but mac os x crashes in attempt to use 
allocated memory (all configurations have 16GB memory)

that is my story

I’m sure that clang analyzer is smart (I’m serious) 

but I have a case on my hands and I have to fix it. I have a feeling that we 
have the very rare case where clang is too smart :)))

unlike g++ or VS2013

of course I can refactor the code (for example to use std::vector<double> 
instead of double*), but code in question is old

and that kind of refactoring will require a lot of efforts.



> On Jul 4, 2016, at 8:03 PM, Steve Sisak <[email protected]> wrote:
> 
> Dmitri,
> 
> The clang code generator and static analyzer are very smart — I’m pretty sure 
> that, for a small malloc where a pointer to the data is never passed outside 
> the current function, the malloc/free can be replaced with a buffer in on the 
> stack — equivalent of alloca().
> 
> WAYRTTD? Your test case may be too contrived.
> 
> Are you just trying to understand why malloc() is getting optimized out or 
> are you trying to find an actual bug? 
> 
> If you’re testing for a compiler bug, pass the pointer to an external 
> function whose implementation the complier can’t see:
> 
> create a file foo.c containing
> 
> void foo(char* baz);
> 
> void foo(char* baz)
> {
>       // whatever logging you want
> }
> 
> then in your code:
> 
> void foo(char* baz);
> 
>    if(data == NULL) {
>        printf("data == NULL\n");
>        return 1;
>    } else {
>       foo(data);
>        for(size_t i = 0; i < need_size; ++i) {
> #if 0
>            size_t c = i % 64;
>            c += 63;
>            data[i] = c;
> #else
>            data[i] = 'A';
> #endif
>        }
>        printf("data != NULL <<%c>>\n", data[0x10000]);
>    }
>    free(data);
> 
> 
> For instance, in your code, if the compiler can see you’re only touching the 
> first 100 bytes of *data and you’re never doing anything that could pass a 
> pointer to the data out of scope, it could just return a pointer to a 100 
> byte block on the stack and no-op the malloc and free and still generate 
> correct behavior. You can defeat this by making the code between malloc() and 
> free() sufficiently complex.
> 
> Also, you may want to check out this document: 
> https://developer.apple.com/library/prerelease/content/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html
>  
> <https://developer.apple.com/library/prerelease/content/documentation/Performance/Conceptual/ManagingMemory/Articles/MemoryAlloc.html>
> 
> as it has a fair bit of information about how malloc actually works.
> 
> HTH,
> 
> -Steve
> 
> 
> 
>> On Jul 4, 2016, at 4:48 PM, Dmitry Markman <[email protected] 
>> <mailto:[email protected]>> wrote:
>> 
>> another observation
>> 
>> the following code
>> 
>> 
>>    char *data = (char *)malloc(need_size);
>> 
>>    if(data == NULL) {
>>        printf("data == NULL\n");
>>        return 1;
>>    } else {
>>        for(size_t i = 0; i < need_size; ++i) {
>> #if 0
>>            size_t c = i % 64;
>>            c += 63;
>>            data[i] = c;
>> #else
>>            data[i] = 'A';
>> #endif
>>        }
>>        printf("data != NULL <<%c>>\n", data[0x10000]);
>>    }
>>    free(data);
>> 
>> 
>> returns
>> 
>> data != NULL <<A>>
>> Program ended with exit code: 0
>> 
>> but if you replace #if 0 to #if 1
>> 
>> it started to behave correctly (data = NULL)
>> 
>> dm
>> 
>> 
>> 
>> 
>> 
>> 
>>> On Jul 4, 2016, at 4:20 PM, Carl Hoefs <[email protected] 
>>> <mailto:[email protected]>> wrote:
>>> 
>>> 
>>>> On Jul 4, 2016, at 12:58 PM, Clark Cox <[email protected] 
>>>> <mailto:[email protected]>> wrote:
>>>> 
>>>> Malloc effectively *never* returns NULL. 
>>> 
>>> It does seem that malloc returns NULL on error...
>>> 
>>> #include <stdlib.h>
>>> #include <stdio.h>
>>> 
>>> int main(int argc, const char * argv[]) {
>>>  size_t need_size = 0x1000000000000;
>>> 
>>>  char *data = "dummy";      // data ptr is not NULL
>>>  data = malloc(need_size);  // data ptr overwritten
>>> 
>>>  if(data == NULL) {
>>>      printf("ERROR data == %p\n",data);  // <----- data is NULL
>>>      return 1;
>>>  } else {
>>>      printf("OKAY data != NULL: %p\n",data);
>>>  }
>>>  data[0] = 'c';
>>> 
>>>  free(data);
>>> 
>>>  return 0;
>>> }
>>> 
>>> mtest(3008,0x7fff786d1300) malloc: *** mach_vm_map(size=281474976710656) 
>>> failed (error code=3)
>>> *** error: can't allocate region
>>> *** set a breakpoint in malloc_error_break to debug
>>> ERROR data == 0x0
>>> 
>>> 
>> 
>> Dmitry Markman
>> 
>> 
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Xcode-users mailing list      ([email protected] 
>> <mailto:[email protected]>)
>> Help/Unsubscribe/Update your Subscription:
>> https://lists.apple.com/mailman/options/xcode-users/sgs-lists%40codewell.com 
>> <https://lists.apple.com/mailman/options/xcode-users/sgs-lists%40codewell.com>
>> 
>> This email sent to [email protected] <mailto:[email protected]>

Dmitry Markman

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/xcode-users/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to