Unresolved externals on Windows static release build. Help!

488 views
Skip to first unread message

Dale Curtis

unread,
Jul 26, 2012, 7:21:43 PM7/26/12
to Chromium-dev
I recently landed support for allocating aligned memory in base/memory/aligned_memory.h. On Windows this uses _aligned_free() and _aligned_malloc() as defined here:

The aligned_memory_unittest uses these methods and compiles and runs fine on all platforms. I have another CL out now which tries to use these methods for some SSE media allocations:


However, when building Chrome Release on Windows as a static library, I get the following failures:

Creating library ..\build\Release\lib\content_shell.lib and object ..\build\Release\lib\content_shell.exp media.lib(sinc_resampler.obj) : error LNK2019: unresolved external symbol __aligned_free referenced in function "void __cdecl base::AlignedFree(void *)" (?AlignedFree@base@@YAXPAX@Z) base.lib(aligned_memory.obj) : error LNK2019: unresolved external symbol __aligned_malloc referenced in function "void * __cdecl base::AlignedAlloc(unsigned int,unsigned int)" (?AlignedAlloc@base@@YAPAXII@Z) ..\build\Release\content_shell.exe : fatal error LNK1120: 2 unresolved externals

I'm able to reproduce this locally, but have no idea why this is happening. Any Windows experts out there know what I'm doing wrong?

Thanks in advance,

- dale

Scott Graham

unread,
Jul 26, 2012, 7:30:14 PM7/26/12
to dalec...@chromium.org, Chromium-dev
I don't know if this is relevant, but we do some unusual things on Windows to replace parts of libc with our own allocator functions.


I see align there, but not the functions you name. It might be worth a look to see if where/how those functions are defined in the CRT and/or our replacements.

--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev

Dale Curtis

unread,
Jul 26, 2012, 9:13:59 PM7/26/12
to Scott Graham, Chromium-dev
Thanks for the pointer Scott! That was indeed the issue, removing "align" from the list of removed objects allows Chrome to link correctly.

Do you know if removing this file is the correct solution? TCMalloc seems to test that _aligned_free() and _aligned_malloc() are properly captured here:

1087     // Windows has _aligned_malloc.  Let's test that that's captured too.
1088 #if (defined(_MSC_VER) || defined(__MINGW32__)) && !defined(PERFTOOLS_NO_ALIGNED_MALLOC)
1089     p1 = _aligned_malloc(sizeof(p1) * 2, 64);
1090     CHECK(p1 != NULL);
1091     VerifyNewHookWasCalled();
1092     _aligned_free(p1);
1093     VerifyDeleteHookWasCalled();
1094 #endif


But also has a comment elsewhere:

284   // malloc.h also defines these functions:
285   //   _aligned_malloc, _aligned_free,
286   //   _recalloc, _aligned_offset_malloc, _aligned_realloc, _aligned_recalloc
287   //   _aligned_offset_realloc, _aligned_offset_recalloc, _malloca, _freea
288   // But they seem pretty obscure, and I'm fine not overriding them for now.
289   // It may be they all call into malloc/free anyway.

Scott Graham

unread,
Jul 26, 2012, 9:24:56 PM7/26/12
to Dale Curtis, Chromium-dev
On Thu, Jul 26, 2012 at 6:13 PM, Dale Curtis <dalec...@chromium.org> wrote:
Thanks for the pointer Scott! That was indeed the issue, removing "align" from the list of removed objects allows Chrome to link correctly.

Do you know if removing this file is the correct solution? TCMalloc seems to test that _aligned_free() and _aligned_malloc() are properly captured here:

Sorry, I don't know much about them, so I'm not sure what the correct solution is. I feel like we should probably be removing "everything" related to allocation and replacing them with versions from TCMalloc, unless some of the functions are higher level and documented to be implemented in terms of other ones.

I don't think Chromium uses the runtime patching (the second version you found) in favour of the static replacement, but I could be mistaken.

Jim Roskind

unread,
Jul 26, 2012, 9:49:07 PM7/26/12
to dalec...@chromium.org, Scott Graham, Chromium-dev, Kai Wang
[Comments instigated by Ryan Sleevi pointing out this thread]

The general philosophy for TCMalloc support on Windows was to remove all Windows run-time-library code that called directly (under the covers) into the windows allocator, and then replace it with equivalent code that we directed into the allocator of the day (typically TCMalloc).

In contrast, if you "remove align from the list of removed objects," you have put back in place the Windows flavor. This is generally dangerous, as it *might* call into the Windows allocator.  Such calls would probably initialize a pile of stuff, including possibly doing some virtual allocs, and *might* leave us in a messed up situation (at a minimum, with a pile of allocated, but *never* ever used memory).

You found a test that verifies that that if we have an aligned_malloc (as evidenced by a macro define), it is at least sometimes based on calls into functions that we have indeed hooked.  Note that it is possible that *sometimes* it calls into (for example) malloc(), which we have nicely hooked, and will safely redirect.  It is also possible that sometimes (when the alignment is of a different size? When some allocation is having trouble? other?) that it makes calls into the internals of the windows allocator :-(.

My expectation is that to be safe (you never know what the next flavor of Windows run time library will do!!), you should provide a re-implementation of these functions in our stubs, that are correctly routed to the desired code (depending on whether we set the environment variable one way or another).

I think the place for placing such re-directions and re-implementations is src/base/allocator/allocator_shim.cc

thanks,

Jim

Dale Curtis

unread,
Jul 27, 2012, 12:45:09 AM7/27/12
to Jim Roskind, Scott Graham, Chromium-dev, Kai Wang
Thanks for the info Jim, even if it's not what I was hoping to hear. Reimplenting _aligned_malloc() and _aligned_free() doesn't look too difficult for TCMalloc, just piping to tc_memalign(), but jemalloc doesn't look like it exposes a "je_memalign" method, nor would the windows heap allocators. I'll play around with this tomorrow, but it looks like a yak shave at first glance.

If I can't find a clean way to modify allocator_shim, instead I'll probably drop _aligned_malloc() + _aligned_free()  in favor of over allocating by alignment-1 bytes using malloc() and manually aligning the pointer. I don't expect a lot of these aligned allocations currently.

Some followup questions after looking at this: Is allocator_shim only used on Windows? I see that it's excluded from linux, freebsd, solaris in the gyp and Mac doesn't seem to include the allocator.gyp at all. Is this expected to change? The posix_memalign/memalign methods I'm using on the other platforms for AlignedAlloc would need to be overridden as well then correct?

- dale

James Robinson

unread,
Jul 27, 2012, 12:48:53 AM7/27/12
to dalec...@chromium.org, Jim Roskind, Scott Graham, Chromium-dev, Kai Wang
On Thu, Jul 26, 2012 at 9:45 PM, Dale Curtis <dalec...@chromium.org> wrote:
Thanks for the info Jim, even if it's not what I was hoping to hear. Reimplenting _aligned_malloc() and _aligned_free() doesn't look too difficult for TCMalloc, just piping to tc_memalign(), but jemalloc doesn't look like it exposes a "je_memalign" method, nor would the windows heap allocators. I'll play around with this tomorrow, but it looks like a yak shave at first glance.

If I can't find a clean way to modify allocator_shim, instead I'll probably drop _aligned_malloc() + _aligned_free()  in favor of over allocating by alignment-1 bytes using malloc() and manually aligning the pointer. I don't expect a lot of these aligned allocations currently.

Some followup questions after looking at this: Is allocator_shim only used on Windows? I see that it's excluded from linux, freebsd, solaris in the gyp and Mac doesn't seem to include the allocator.gyp at all. Is this expected to change? The posix_memalign/memalign methods I'm using on the other platforms for AlignedAlloc would need to be overridden as well then correct?


allocator_shim and runtime allocator selection (the feature allocator_shim enables) are only used on Windows.  We use tcmalloc on linux, but it's hooked up differently.  On Mac we just use the system malloc.

- James

Dale Curtis

unread,
Aug 2, 2012, 2:07:58 PM8/2/12
to James Robinson, Jim Roskind, Scott Graham, Chromium-dev, Kai Wang
To close the loop on this, I fixed this in http://crrev.com/149537

Jim was kind enough to review my changes to add the _aligned_malloc() and _aligned_free() methods to allocator_shim. So behind the scenes these methods are properly routed to tcmalloc, jemalloc, or the windows heap allocators depending on the environment variable.

Thanks again everyone!

- dale
Reply all
Reply to author
Forward
0 new messages