Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
Developer Community or GitHub with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
I have pretty big XML with linker rules and Link All option enabled. NO LLVM.
With SDK Only linker everything works OK.
With LLVM everything works OK.
ld: don't know how to convert instruction ecc9f60c referencing _mono_create_corlib_exception_0.island.3 to thumb in 'SM_Machines_MiniGames_MiniGame270__ConvertResponceToMessagec__Iterator0_Reset' from /Users/grigoryp/Documents/sm.ng/Build/Obj/Debug/SM.IOS/mtouch-cache/SM.Machines.dll.armv7.o for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
MTOUCH: error MT5309: Native linking error: don't know how to convert instruction ecc9f60c referencing _mono_create_corlib_exception_0.island.3 to thumb in 'SM_Machines_MiniGames_MiniGame270__ConvertResponceToMessagec__Iterator0_Reset' from /Users/grigoryp/Documents/sm.ng/Build/Obj/Debug/SM.IOS/mtouch-cache/SM.Machines.dll.armv7.o for architecture armv7
MTOUCH: error MT5201: Native linking failed. Please review the build log and the user flags provided to gcc: -L /Users/grigoryp/Documents/sm.ng/Src/SM/SM.IOS/../../Playtika/Monosyne/Monosyne/ThirdParty/Libs/IOS/unified/ -lFreetype2 -ltremor -lzlib -lBinkiOS -framework AudioToolbox
MTOUCH: error MT5202: Native linking failed. Please review the build log.
Ah, i also have Debugging enabled. Disabling it fixes the issue.
This happens when the native code we generate for one of your assemblies ends up hitting size limitations in the native (Mach-O) file format.
One potential workaround which worked for one client is to add the following to the additional mtouch arguments:
other workarounds are mentioned here: https://bugzilla.xamarin.com/show_bug.cgi?id=1102#c25 (some of which you've already found).
If you give us access to your entire project (since this is a size issue it's not possible to create a small test case for it) we can have a look and see if we can improve our codegen somewhere.
Hi, i think it makes sense to look at root of the problem - codegen in Monotouch. I've disassembled biggest obj file (Mach-O one), and found many functions like:
and other delegates.
Basically they contain same code. (and for example GetCompetionAction is really
I believe that i touched problem of huge Mach-O size because of heavy usage of async/await based code.
I see a solution of rewriting code without async/await, but this will contradict with statements from http://xamarin.com/platform about C# features
@Zoltan, can you have a look?
I calculated amount of machine code in one of our assemblies.
Numbers = percent of total count of A32 instructions per namespace
Small namespaces with <0.5% are omitted
More that 1/2 of assembly is the code from System namespace or delegates.
0,55 = _SM_Shared_BannerInLobby
3,33 = _SM_Shared_Common
3,14 = _SM_Shared_Gifts
0,67 = _SM_Shared_LevelUp
2,76 = _SM_Shared_LuckySpin
2,41 = _SM_Shared_Machines
4,45 = _SM_Shared_Payments
1,05 = _SM_Shared_PersonalOffers
1,30 = _SM_Shared_PiggyBank
0,62 = _SM_Shared_RegistrationReminders
1,33 = _SM_Shared_Settings
1,31 = _SM_Shared_TotalRewardsSocial
0,59 = _SM_Shared_Tournamania
0,79 = _SM_Shared_Utils
0,85 = _System_Array_InternalArray
1,03 = _System_Array_InternalEnumerator
1,13 = _System_Array_qsort
17,69 = _System_Collections_Generic
1,31 = _System_Linq_Enumerable
0,59 = _System_Reactive_Subjects
19,84 = _System_Runtime_CompilerServices
6,95 = _System_Threading_Tasks
8,79 = _wrapper_delegate_invoke
To be more clear, what i did:
I took .armv7.llvm.o file, disassembled with IDA, created .map file, calculated sizes of funcs and grouped by func export name substring (till 3rd underscore)
Copying all code to 1 project reduced binary on 3megs. Seems some System.Collections.Generic code is duplicated for each assembly.
This is an awful solution for a big project we have.
These problems usually happen when code uses lots of structs/enums mixed with generics, since the AOT compiler needs to generate different code for each, so
using List<AStruct> and List<BStruct> will cause two list classes to be generated.
I'd suggest converting some of the structs used in the code to classes.
The next major xamarin.ios release contains improvements to this, enums will be handled better, i.e. List<AEnum> and List<BEnum> will be shared.
Sounds great, as enums by default share same underlying type.
Can we do something with async/await ?
AsyncMEthodBuilder, VoidTaskResult and some other bcl types are declared as structs. Unfortunately that gives a huge amount of pretty repeating boilerplate(i checked asm - methods differ only by offsets, hopefully it can be parametrized and code can be deduplicated).
For a method like:
Is the SM_Machines_MiniGames_MiniGame332_Rounds_SaveWendy_WendyRound
type a struct type or a normal class ?
Maybe there are some good news with this thing ?
This is an important bug, as all that CompilerServices stuff takes >15% of binary, which is critical on IOS, because Apple has 80 000 000 bytes limitation on 2arch binary.
async/await heavy app can reach this limit pretty fast.
Of course Xamarin sample apps, chats, RSS readers, calculators would never have this problem. But app i've attached is bigger than that cool presentation stuff, it is an app from market top, that earns big money for years, and is beging rewritten in C#.
Sad thing is that original app (same functionality) had binary about 30 megs, and we have 90.
Or if it is by-design - just say that. Then everyone who has encountered same problem will know that this 15% of binary are essential and won't be removed later, and issue should be fixed by another instruments. Partially or fully rewriting into Cpp, or Swift, or whatever.
But any architectural decisions are quite painful when issue lies on pretty low level (codegen).
Most apps don't use that many async methods, probably thats why this issue was not noticed before. It is an implementation problem, c# generates lots of instantiations of the AsyncMethodBuilder etc. classes, and our code generator is not yet good enough to share the code for them.
The duplicate code generation for the AsyncMethodBuilder classes should be fixed in mono master 082de058c39a6e6e3b8d6840471bd02ac1ab90d5.
Great job! Looking forward to try the monotouch build with the fix.
Also wrappers are duplicated, i believe they bring few megs to the build size in code that uses delegates heavily. _XXX_wrapper_delegate_invoke_System_Func_1_System_Collections_Generic_Dictionary_2_string_YYY_invoke_TResult
Interesting thing is the mono_eh_frame that takes ~15% of binary size. Is there any option for us to change our code in some way to reduce it ?
There is no way to reduce that right now, but it shouldn't be that big. Will look at it.
The partial fix for async code size will be on the next stable release.
About binary size:
8.10.4 from Stable produces binary that is 14 megs bigger than 22.214.171.124. We get 89megs so we can't even submit to AppStore. latest 8.11 build are a bit better, but still too bad. They add +6megs to the result of 126.96.36.199.
About this bug:
We still can't build a debug build, because of this issue. Even when i select ONLY ARMv7 it crashes. Codegen is still inefficient :(
188.8.131.52 is a bug fix release, the only size related change is the fix for the AsyncMethodBuilder code generation, so it should improve code size related to 8.10.2.
To be clear:
1. Problem with building in Debug mode still exists. We can only build 1arch in release mode with enabled linker.
2. Binary size problem still exists (we fight for every kilobyte, not to reach 80 megs).
Guys, you should solve it somehow. It is not even funny.
Are you planning to sell Xamarin only to startup teams that write 3 screen sample apps ?
Does the current stable 184.108.40.206 release improve anything for you ? It should only include bug fixes plus the fix for the AsyncMethodBuilder issue, so it should definitely lead to smaller executable sizes than 220.127.116.11.
8.13 is an alpha release so some things might be better, some might be worse.
I'm having the same issue, related to the binary size. In my case, enabling LLVM lowers the binary size, making it runnable, but not debuggable.
X.I. 9.4 helps with that.
So workaround is to update (but keep in mind that 9.4 is very buggy, exceptions are not caught in "catch"es in some cases)
That bug is probably:
I don't see any activity on this bug in 18months! Commonent #37 suggested that updating to latest version did fix the issue, so marking this as resolved. Please reopen the bug if you still encounter this issue