Bug #75571 function attribute "static" of ib_heap_malloc may cause compilation error
Submitted: 21 Jan 2015 8:47 Modified: 22 Jan 2015 7:34
Reporter: Jeff Huang Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Compiling Severity:S3 (Non-critical)
Version:5.7 OS:Any
Assigned to: CPU Architecture:Any
Tags: ib_heap_malloc, inline, static

[21 Jan 2015 8:47] Jeff Huang
Description:
In storage/innobase/include/ut0vec.ic, the attribute of function ib_heap_malloc() is UNIV_INLINE, which is defined as "static inline".  The same happens to function ib_heap_allocator_create().  Please note, there is a reference to ib_heap_malloc in ib_heap_allocator_create, at line #90.  See below.

 30 UNIV_INLINE
 31 void*
 32 ib_heap_malloc(
 33 /*===========*/
 34     ib_alloc_t* allocator,  /* in: allocator */
 35     ulint       size)       /* in: size in bytes */
 36 {
 37     mem_heap_t* heap = (mem_heap_t*) allocator->arg;
 38
 39     return(mem_heap_alloc(heap, size));
 40 }
...
 78 UNIV_INLINE
 79 ib_alloc_t*
 80 ib_heap_allocator_create(
 81 /*=====================*/
 82     mem_heap_t* heap)       /* in: heap to use */
 83 {
 84     ib_alloc_t* heap_alloc;
 85
 86     heap_alloc = (ib_alloc_t*) mem_heap_alloc(heap, sizeof(*heap_alloc));
 87
 88     heap_alloc->arg = heap;
 89     heap_alloc->mem_release = ib_heap_free;
 90     heap_alloc->mem_malloc = ib_heap_malloc;
 91     heap_alloc->mem_resize = ib_heap_resize;
 92
 93     return(heap_alloc);
 94 }

In other cc files, e.g. this one storage/innobase/fts/fts0fts.cc.  See below.  It calls ib_heap_allocator_create().

6992 UNIV_INTERN
6993 void
6994 fts_drop_orphaned_tables(void)
6995 /*==========================*/
6996 {
...
7015     heap_alloc = ib_heap_allocator_create(heap);

According to C standard, static functions are functions that are only visible to other functions in the same file.  So, it's legit for a compiler to alter name of static functions, as long as all callers are aware of that in the same source file.  Another thing we need to know is that, "inline" is only a hint to compilers, which could decide whether to inline a particular function or not.

I'm using Intel compiler (icc) and turned on inter-procedural optimization (-ipo option).  It appears that, with IPO, icc inlined ib_heap_allocator_create() at its call sites, but didn't inline ib_heap_malloc().  In addition, icc renamed ib_heap_malloc to different names in storage/innobase/include/ut0vec.ic and in storage/innobase/fts/fts0fts.cc respectively, in order to avoid collision of static functions or variables.  Literally, we now see two different symbols, ib_heap_malloc_A and ib_heap_malloc_B, in these two object files.  During linking, linker will report unresolved symbol ib_heap_malloc_B in storage/innobase/fts/fts0fts.cc.o.

How to repeat:
Not easy to reproduce the linking error.  There are some prerequisite steps, before you could see the error.  Please let me know, if you really need to reproduce.

Suggested fix:
A possible fix is to remove static attribute by changing

  #define UNIV_INLINE static inline

to

  #define UNIV_INLINE inline

This should have no negative impact to MySQL.
[21 Jan 2015 14:45] MySQL Verification Team
Can you please, specify what is exactly the C standard that you are referring to.

Also, what is a version of Intel's compiler that is returning the error.

It is possible that we do not maintain either.

Last, but not least, do you have problems with latest version of 5.6 too ???
[22 Jan 2015 7:34] Jeff Huang
Hello Sinisa,

After further investigation, I found that the definition of function ib_heap_malloc, as part of storage/innobase/include/ut0vec.ic, is actually included in storage/innobase/fts/fts0fts.cc.  As a result, there shouldn't be a unresolve symbol error at all.  I did a make clean this morning and rebuilt everything.  Compilation worked perfect.  SORRY for the false alarm.  Have a good day!
[22 Jan 2015 15:12] MySQL Verification Team
Thank you for checking it out and, please, when you hit upon a real bug, do report it here.