I'm experimenting with Dll rebasing on a small test solution running on .net4 consisting of one small .exe and three small .Dlls. The assembly references have been set up correctly and the program compiles and runs just fine.
The aim of this exercise is to examine how rebasing works so that I can tie it in with ngen and get performance increases in a massive project I'm working on.
I've tried many different methods of rebasing the Dlls and monitored the results using vmmap, the visual studio module debugger window and process explorer; nothing has been successful so far:
I've set the Build->Advanced->DLL Base Address setting to 0x41000000, 0x42000000 and 0x43000000 for Dll1.dll, Dll2.dll and Dll3.dll respectively. These addresses were definitely saved as the preferred base address in each of the Dlls, but for each run the Dlls rebased their images erratically to many different locations in memory.
I've tried using this application. The logs it generate show that the Dlls do indeed have the preferred base address (as selected by me) built in, however at runtime the results are still erratic
I've tried using ngen. This results in the .ni versions of the Dlls being loaded alongside the original Dlls, and all 6 of them having erratic memory locations nowhere near the ones I asked for.
I've tried sticking my images in the GAC. It was heartening to see that only the GAC'd versions of the Dlls were loaded, however their memory locations were still erratic.
I've tried what feels like every combination of the above. No success.
Poking around at runtime using VMMap shows that there is a massive gap of available memory in the address space between 0x10000000 and 0x50000000, so there should be no collisions and no need for Dll rebasing to occur. The Dlls are also very small and the 0x01000000 gap I'm leaving between them is extremely generous, so they shouldn't be colliding with each other.
What am I missing?
My main reference during this exercise has been this article, which is highly informative, but was written in 2006 for .Net2: Has something fundamental changed between then and now?
I seriously doubt it makes much difference, but here's the code I'm using just in case:
Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Dll1;
using Dll2;
using Dll3;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Thread.CurrentThread.Name = "Poodle";
Console.ReadLine();
//Thread.Sleep(10000);
Blah();
}
static void Blah()
{
Console.WriteLine(Class2.shrooms(5, 'h'));
Class3.teenAngst();
Class1.Wait();
}
}
}
Class1.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dll1
{
public static class Class1
{
public static void Wait()
{
Console.ReadLine();
Console.Write(" ");
}
}
}
Class2.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dll2
{
public static class Class2
{
public static string shrooms(int argc, char argv)
{
return "Ranchdaddyx ";
}
}
}
Class3.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Dll3
{
public static class Class3
{
public static void teenAngst()
{
Console.Write("Belonging ");
}
}
}
It is not necessary to rebase JIT compiled code:
JIT-compiled code does not have a rebasing problem since the addresses
are generated at run time based on where the code is placed in memory.
Also, MSIL is rarely affected by base address misses since MSIL
references are token-based, rather than address-based. Thus when the
JIT compiler is used, the system is resilient to base address
collisions.
.NET assemblies and DLL rebasing
If I want to rebase my DLL's, how do I go about doing it?
http://msdn.microsoft.com/en-us/magazine/cc163610.aspx
http://support.microsoft.com/kb/969305
It turns out that ASLR (Address Space Layout Randomization) is the culprit of my confusions. Apparently you can turn it off, but you're sacrificing safety/making a lot of work for yourself. I consider the whole adventure a failed experiment.
.Net .dll's are a very different beast from their unmanaged equivalents. I honestly didn't think that rebasing was relevant.
Check out this MSDN article. Which, among other things, encourages you to NOT rebase. And gives at least one compelling reason NOT to (it could invalidate the signature of a strongly signed assembly). The article also discusses the potential benefits of NGEN (as does your link):
CLR Inside Out
Related
In Nunit C# Im trying to open the application only once and make modification to it, for example i created this demo of Notepad application. In my real time project,i just have to log in to the application just once and execute all 100 test cases and only then close the Desktop application. Kindly tell me what am i doing wrong here,thanks a lot! Btw,im new to C#
using NUnit.Framework;
using OpenQA.Selenium.Remote;
using System;
using OpenQA.Selenium;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace Notepad
{ }
[SetUpFixture]
public class BaseClass
{
public static IWebDriver driver;
[OneTimeSetUp]
public static void AssemblyInitalize()
{
var dc = new DesiredCapabilities();
dc.SetCapability("app", #"C:\\Windows\\System32\\notepad.exe");
driver = new RemoteWebDriver(new Uri("http://localhost:9999"), dc);
Thread.Sleep(5000);
}
[OneTimeTearDown]
public static void oneTearDown()
{
driver.FindElement(By.Id("Close")).Click();
}
}
---First Test---
namespace Notepad
{ [TestFixture]
public class Notepad2:BaseClass
{
[Test]
public void test2()
{
driver.FindElement(By.Id("15")).SendKeys("My Teacher ");
}
}
}
---- Second Test Class ----
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
namespace Notepad
{ [TestFixture]
public class NoteTest : BaseClass
{
[Test]
public void Test()
{
driver.FindElement(By.Id("15")).SendKeys("...is Coming now");
}
}
}
Regarding SetUpFixture, the first answer is incorrect.
SetUpFixture works exactly the same way as it has always worked. If you have a SetUpFixture, it's OneTimeSetUp and OneTimeTearDown methods will run once for all the fixtures under the same namespace.
On the other hand, inside a TestFixture the OneTimeSetUp and OneTimeTearDown methods run just once for the fixture itself.
In other words, the methods run "one time" within the particular scope in which they are used, namespace or fixture.
The problem is that you are using the same class as both a SetUpFixture and as the base class for all your TestFixtures. That means if you have n test fixtures, it will run n + 1 times! That's what you are seeing.
SetUpFixtures do not (have never had) anything to do with fixture inheritance. You should either make your class a SetUpFixture or a TestFixture base class. If, for whatever reason, you need both, then use two classes. In this case, you need only the SetUpFixture, without the inheritance.
When to inherit from a base class: When you want the same code to execute many times, once for each fixture. Note that your base class, when used for one-time setup and teardown in this way, should normally not be marked as a TestFixture.
When to use a SetUpFixture: When you want some code to execute only once, before every any fixture runs and again once after all the fixtures have run.
In your example, you are using a SetUpFixture to control the timing of the initialization. You are using inheritance to allow you to share the driver. Problem is that the OneTimeSetUp in the base class is actually part of each test fixture and you don't want that.
I'd be concerned about a hundred or so tests all using the same driver. I've seen some people use one driver per test and others one driver per fixture_. Using one for __everything implies that you are being extraordinarily careful that each test cleans up after itself and restores the driver to the same state. I doubt that's possible.
However, as an exercise, here is how to do it if you really want to:
1. Have a base class with nothing but the driver member.
2. Derive the SetUpFixture from the base class and create / destroy the driver there.
3. Derive the TestFixtures from the same base class. They use but don't change the driver.
From the documentation, OneTimeSetup is called once before all tests in a TestFixture. Your example has two fixtures, so the set up is called twice. You need to have all your tests in the same Fixture.
This behaviour is different to the old [Setup] on SetupFixture attribute, which ran once for all tests in a namespace.
I'm trying to follow this answer https://stackoverflow.com/a/47295752/1237135, in order to get a list of IIS Express websites, which involves referencing Microsoft.Web.dll (this is a .NET assembly, but presumably it uses COM calls) and calling this code
using (var runtimeStatusClient = new RuntimeStatusClient())
{
var workerProcess = runtimeStatusClient.GetWorkerProcess(19464);
//there's more but this is all that is needed for failure
}
It actually works, the code runs and has meaningful data, however a few seconds after it completes I get this error
System.InvalidCastException:
'Unable to cast COM object of type 'System.__ComObject'
to interface type 'Microsoft.Web.RuntimeStatus.IRsca2_WorkerProcess'.
This operation failed because the QueryInterface call on the COM component
for the interface with IID '{B1341209-7F09-4ECD-AE5F-3EE40D921870}' failed
due to the following error: No such interface supported (Exception from
HRESULT: 0x80004002 (E_NOINTERFACE)).'
E_NOINTERFACE is often associated with not using an STAThread model, but I've verified that the thread is STA.
The code works without error in a Console app environment, but not WPF.
The answer above mentions
I looked into RegisteredUrlsInfo (in Microsoft.Web.dll) as well and
found that it's using two COM interfaces,
IRsca2_Core (F90F62AB-EE00-4E4F-8EA6-3805B6B25CDD)
IRsca2_WorkerProcess (B1341209-7F09-4ECD-AE5F-3EE40D921870)
And I saw another answer https://stackoverflow.com/a/1058978/1237135 that talks about
Try adding this to your App.exe.manifest:
iid="{C677308A-AC0F-427D-889A-47E5DC990138}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
baseInterface="{00000000-0000-0000-C000-000000000046}" tlbid =
"{PUT-YOUR-TLB-GUID-HERE}" /> Where TLBID can be found from your
Visual Studio generated Native.Namespace.Assembly.Name.manifest,
looking like this:
but I'm unclear if this applies here.
I also wondered if it's DLL Hell but that wouldn't explain why it works from a Console, would it?
EDIT: minimal reproduction.
Create a WPF project (I used 4.6.1 runtime) and in the codebehind for the MainWindow I used
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp2
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
using (var runtimeStatusClient = new Microsoft.Web.RuntimeStatus.RuntimeStatusClient())
{
var workerProcess = runtimeStatusClient.GetAllWorkerProcesses();
}
}
}
}
The only hard part is you need to find and reference Microsoft.Web.DLL (which if you have IIS Express on your machine should be in your GAC). You can do a Windows search on your C:\ drive and it will probably be somewhere like C:\Windows\assembly\GAC_MSIL\Microsoft.Web\7.1.0.0__31bf3856ad364e35
Do that and you'll see the problem.
Apparently I made 2 fatal assumptions:
Console Apps use STA. However this isn't true, it seems by default they are MTA. That figures I suppose as desktop apps have to explicitly state STA in the Main method.
To do COM interop you have to use STA. I assumed this because using STA is the go-to solution to E_NOINTERFACE problems on the web. However as I understand it now, some COM can use MTA. It appears for Microsoft.Web.DLL, you need MTA.
So my solution is to create a new thread (which will use MTA by default), eg.
public MainWindow()
{
InitializeComponent();
//Do use ThreadPool instead of this...
Thread thread = new Thread(new ThreadStart(() => { GetWebsites(); }));
thread.Start();
}
void GetWebsites()
{
I’ve compiled libsass 3.3.6 into a DLL with VS 2015 using the included solution files. Running the code below causes the program to crash immediately with no output.
using System;
using System.Runtime.InteropServices;
namespace Sass.Cli {
static class Sass {
[DllImport(#"C:\...\libsass\win\bin\libsass.dll")]
public static extern String libsass_version();
}
class Program {
static void Main(string[] args) {
Console.WriteLine(Sass.libsass_version());
}
}
}
The source for the invoked function is at sass.cpp:61.
const char* ADDCALL libsass_version(void)
Both the DLL and the above code were compiled for x86. Running the VS debugger on crash gives me the following exception: Unhandled exception at 0x771A9841 (ntdll.dll) in Sass.Cli.exe: 0xC0000374: A heap has been corrupted (parameters: 0x771DC8D0).
Is this something that can be fixed or that I’ve overlooked? Or is it just the case that libsass DLLs aren’t currently working?
When a string is used as a return type then the framework assumes it was allocated by calling CoTaskMemAlloc. It then copies the content of the string and deallocation by calling CoTaskMemFree. That is the explanation for your error.
Solve it by changing the return value to IntPtr and getting the string content with Marshal.PtrToStringAnsi. You won't need to deal located anything since this version string will be static.
I can't tell what the calling convention is. You should check the code and docs to find out. Still, this function is so simple that it behaves the same way for both cdecl and stdcall so that can't explain the error. Still, you will need to get it right for the rest of the library.
Note that I am guessing a little here. You've not provided full details. You should consult the code and docs to double check my guesswork.
I am trying to embed managed c# code to c++ (with the help of tutorial in http://www.mono-project.com/Embedding_Mono and examples included in samples).
However I cannot get it to work. I think it is very possible that the problem is with a System.Net.Sockets.TcpClient object (for instance I can access values and methods of some other classes but if I add a TcpClient object to a class I encounter problems.
Here is some simple C# code I wrote to test just adding a TCPClient object
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
}
static void TCPTest()
{
TcpClient TCPClient;
//Console.WriteLine("in tcp test");
}
}
}
And the c++ code is here: http://codepad.org/f9D5bg8u (it is a stripped down version of the mono embedding sample).
When I build the C# code like this,
mono_runtime_invoke (method, obj, NULL, NULL);
in the c++ side exits with code 1.
When I comment that out and try the console.writeline, that works.
I appreciate any suggestions,
Thanks...
I'm writing a wrapper library using C++/CLI for an unmanaged C++ project. The goal is to expose this library to C# applications. Here's what I have so far.
#pragma once
#include "Settings.h"
#include "Settings/SettingsPrivate.h"
public ref class Settings
{
public:
Settings();
virtual ~Settings();
protected:
!Settings();
public:
unsigned char GetModel(int iNumber);
private:
CSettings* m_pSettings;
};
#include "stdafx.h"
#include "Managed/Settings.h"
Settings::Settings()
{
// Pointer to unmanaged object
m_pSettings = new CSettings();
}
Settings::~Settings()
{
this->!Settings();
}
Settings::!Settings()
{
if (m_pSettings)
{
delete m_pSettings;
m_pSettings = NULL;
}
}
unsigned char Settings::GetModel(int iNumber)
{
return m_pSettingss->GetModel(iNumber);
}
The code executes fine in the test application I wrote. The function call succeeds. The problem is that when the GC Finalizes this object, it throws an exception.
An unhandled exception of type 'System.AccessViolationException' occurred in Wrapper.dll
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I can't see any obvious reason why this exception is being thrown. I tried disposing of the object explicitly by calling Dispose from my C# application. It still throws the same exception.
Here's the test application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WrapperTest
{
class Program
{
static void Main(string[] args)
{
Settings settings = new Settings();
byte b = settings.GetModel(0);
settings.Dispose();
return;
}
}
}
Would someone point out what I'm doing wrong??
It was a project configuration error. The code actually ran fine in Release mode.
In debug mode I linked in some release DLL's when I should have been statically linking against debug libraries. Why this caused memory corruption I haven't yet investigated but it has solved the problem.
Otherwise the code posted above is correct.
You should enable more verbose heap debugging functionality. I tested your code and it did not fail for me. I had to use malloc/free instead of new/delete as you didnt define CSettings, however the effect should be the same.
I added this to make sure I had enough heap churn to trigger a failure if their was any corruption;
unsigned char Settings::GetModel(int iNumber)
{
for(int i=0; i < iNumber; i++)
free(malloc(1024));
return iNumber;
}
For me your code worked with no failure. You should look into some of your compilation settings, are you linking to an external library for CSettings? If so you need to make sure the CRT is the same version, etc. Also you know you have to use one of the DLL run time's not /MT or /MTd.