Bug 22033 - Wrong dll linked by linker
Summary: Wrong dll linked by linker
Status: VERIFIED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: master
Hardware: PC Mac OS
: Normal normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-08-12 10:33 UTC by Todd Berman
Modified: 2015-01-13 13:29 UTC (History)
6 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Test Case (751.17 KB, application/zip)
2014-10-29 13:03 UTC, Alex Soto [MSFT]
Details
TestCase using MTD (749.81 KB, application/zip)
2014-10-29 17:42 UTC, Alex Soto [MSFT]
Details
TestCase using modernhttp and .NET handler (749.98 KB, application/zip)
2014-10-31 16:25 UTC, Alex Soto [MSFT]
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and 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 Links.

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.

Related Links:
Status:
VERIFIED FIXED

Description Todd Berman 2014-08-12 10:33:25 UTC
So, this is a bit complex.

I have an iOS application, called 'App'.

I also have an iOS library, called 'LibIOS'.

Finally, I have a PCL library, called 'LibPCL'.

App has a reference to LibIOS and LibPCL, and LibIOS has a reference to LibPCL.

Additionally, LibIOS and LibPCL both depend on a library from NuGet (in this case, ModernHttpClient).

ModernHttpClient is using the Bait and Switch PCL strategy (described in more detail here: http://log.paulbetts.org/the-bait-and-switch-pcl-trick/)

Now, given this structure, the version of the library used in the final application is the one from the PCL lib, not the one from the iOS library, which seems wrong given that the dep from the iOS library is more specific to the platform being linked.
Comment 1 Alex Soto [MSFT] 2014-08-12 16:50:03 UTC
Hello Todd

Without a test case we can only guess how to repro and that's not helpful for anyone and likely to take a lot of time to track that bug down. Could you please provide us a self contained-test case so we can take a look and fix it ASAP?

Cheers

Alex
Comment 2 Todd Berman 2014-08-12 16:51:31 UTC
Hey Alex, happy to do that, does the time I spend building a test case showing a bug in this thing I bought come off my next bill? If so, at what rate? I gave pretty clear instructions that anyone over there should be able to use to create a minimal test case...
Comment 3 Todd Berman 2014-08-14 12:35:52 UTC
Marking as NEW
Comment 4 Alex Soto [MSFT] 2014-10-29 13:03:30 UTC
Created attachment 8544 [details]
Test Case

Test Case
Comment 5 Alex Soto [MSFT] 2014-10-29 13:06:06 UTC
Hello Todd

Could you gift me 5 minutes of your time and confirm this replicates the bug you are seeing? 

Thanks in advance :)

Cheers!
Comment 6 Alex Soto [MSFT] 2014-10-29 17:42:07 UTC
Created attachment 8555 [details]
TestCase using MTD
Comment 7 Todd Berman 2014-10-29 17:58:28 UTC
Hey Alex,

In my testing, this works fine (it uses the proper NativeHandler), which either means 1) the bug has been magically fixed 2) it is more subtle and there is some linker ordering issue.

I was able to confirm that it was using the right dll by looking at what ended up inside the bin/Debug/ folder.
Comment 8 Sebastien Pouliot 2014-10-29 20:20:27 UTC
Hey, the initial sample (comment #4) was incorrect (there's a different issue wrt the storyboard) and why I asked Alex to create another one with MTD.

Now I think there a misunderstanding and, if that's the case, no bug exists.

What's happening is that, in Release, we strip the IL off the assemblies [1]. That's done for both size consideration (smaller size without IL) and to protect the IP of the assemblies (reverse engineering is much harder). Since the IL was AOT'ed into native code the application will work normally.

Now that can make the .dll (in a release .app) look a lot like a "facade" PCL (like the one ModernHttpClient provides) as they both only contain metadata. However the release application will work normally.

Todd, what made you think it was not the "right" assembly ? did it happen only for Release and did the application work ?


[1] that can be turned off using `--nostrip` in the additional mtouch arguments of the project options
Comment 9 Todd Berman 2014-10-29 21:37:49 UTC
Sorry, I only verified that way for this test, in our real use case we know its a bug because it wasn't using NSURLSession-based iOS handler, and instead was using the built in HttpMessageHandler. I know this for 3 reasons:

1) The stacks we got weren't using the NSURLSession stuff
2) The runtime type was the default one, not the iOS specific implementation

(and most obviously)

3) When we fixed this, and added the reference to the App project so it used the right one, we exposed a race condition in ModernHttpClient :)

In the ModernHttpClient case, the application will continue to work w/ the wrong assembly, it will just fall back to the system http handler.
Comment 10 Alex Soto [MSFT] 2014-10-31 16:25:05 UTC
Created attachment 8584 [details]
TestCase using modernhttp and .NET handler

So I updated the test case and added an option to use .NET's implementation

I am testing the client against http://httpbin.org/headers so:

Using modernhttp I get:

ClassicApp[41961:24959276] {
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "en-us", 
    "Connect-Time": "1", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "Total-Route-Time": "0", 
    "User-Agent": "ClassicApp/1.0 CFNetwork/711.1.12 Darwin/14.0.0", 
    "Via": "1.1 vegur", 
    "X-Request-Id": "c1d46013-90f2-46e3-a1e8-8448ee74472b"
  }
}

using .NET's implementation I get:

ClassicApp[41961:24959276] {
  "headers": {
    "Connect-Time": "1", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "Total-Route-Time": "0", 
    "Via": "1.1 vegur", 
    "X-Request-Id": "a92a44d3-5d6d-4536-b0f2-0dbb2ed081cf"
  }
}

As you can see using modernhttp handler it sets the User-Agent and .NET implementation does not.

Also created a native sample that uses directly NSURLSession (which is what modernhttp uses underneath) and got:

HttpClientSample[1585:592573] {
  "headers": {
    "Accept": "*/*", 
    "Accept-Encoding": "gzip, deflate", 
    "Accept-Language": "es-xl", 
    "Connect-Time": "1", 
    "Connection": "close", 
    "Host": "httpbin.org", 
    "Total-Route-Time": "0", 
    "User-Agent": "HttpClientSample/1 CFNetwork/711.1.12 Darwin/14.0.0", 
    "Via": "1.1 vegur", 
    "X-Request-Id": "c285ca03-ce7f-4080-b739-9961863bfead"
  }
}

As you can see both modernhttp and native output matches so it seems to be doing the right thing.
Comment 11 Alex Soto [MSFT] 2014-10-31 16:33:51 UTC
So since modernhttp is using NSURLSession instead of the default NET implementation the right assembly is being used in the final app.

@Todd: is there anything in this sample that could be different from your app ?
Comment 12 Todd Berman 2014-10-31 16:34:39 UTC
So, I am able to replicate my issue if you don't link LibiOS against ModernHttpClient, then the PCL version of ModernHttpClient is used by the linker.
Comment 13 Todd Berman 2014-10-31 16:45:20 UTC
I can also confirm locally that this issue is fixed locally in our project when using current stable.
Comment 14 Mohit Kheterpal 2015-01-13 13:29:09 UTC
As per comment 13, this issue is fixed.

So, I am closing this issue.