question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Is there a way to load debug symbols at runtime without any files

See original GitHub issue

This is what I am trying to do:

class Program
{
	static void Main(string[] args)
	{
		var asmDef = AssemblyDefinition.ReadAssembly(typeof(Test).Module.FullyQualifiedName,
			new ReaderParameters{ReadSymbols = true});
		asmDef.Name.Name += "Fake";
		var typeDef = asmDef.MainModule.GetType(typeof(Test).FullName, runtimeName: true).Resolve();
		var methodDef = typeDef.Methods.Single(m => m.Name == nameof(Test.Print));
		var consoleMethod = typeof(Console)
			.GetMethods()
			.Single(m => m.Name == nameof(Console.WriteLine) && m.GetParameters().Length == 1
			                                                 && m.GetParameters().Single().ParameterType ==
			                                                 typeof(string));
		methodDef.Body.Instructions.Insert(methodDef.Body.Instructions.Count - 1,
			Instruction.Create(OpCodes.Ldstr, "Injected"));
		methodDef.Body.Instructions.Insert(methodDef.Body.Instructions.Count - 1,
			Instruction.Create(OpCodes.Call, asmDef.MainModule.ImportReference(consoleMethod)));
		
		//This one works fine based on the pdb file
		var asm = WriteFileAssembly(asmDef);

		// But this one fails
		//var asm = WriteMemoryAssembly(asmDef);
		
		var type = asm.GetType(typeof(Test).FullName);
		type.InvokeMember(nameof(Test.Print), BindingFlags.InvokeMethod, null,
			Activator.CreateInstance(type), new object[0]);
	}

	private static Assembly WriteFileAssembly(AssemblyDefinition asmDef)
	{
		using var stream = File.Open("test.dll", FileMode.OpenOrCreate);
		asmDef.Write(stream, new WriterParameters {WriteSymbols = true});
		stream.Position = 0;
		// To avoid implicit load by the name
		File.Delete("renamed.pdb");
		File.Move("test.pdb", "renamed.pdb");
		// -----------------------------------
		var pdb = File.OpenRead("renamed.pdb");
		return AssemblyLoadContext.Default.LoadFromStream(stream, pdb);
	}

	private static Assembly WriteMemoryAssembly(AssemblyDefinition asmDef)
	{
		using var stream = new MemoryStream();
		using var symbolsStream = new MemoryStream();
		asmDef.Write(stream, new WriterParameters
		{
			SymbolStream = symbolsStream,
			SymbolWriterProvider = new SymbolsWriterProvider()
		});
		stream.Position = symbolsStream.Position = 0;
		return AssemblyLoadContext.Default.LoadFromStream(stream, symbolsStream);

		// This one doesn't work too with the same error
		// var pdb = File.OpenRead("renamed.pdb");
		// return AssemblyLoadContext.Default.LoadFromStream(stream, pdb);
	}

	private class SymbolsWriterProvider : ISymbolWriterProvider
	{
		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, string fileName)
			=> throw new NotSupportedException();

		public ISymbolWriter GetSymbolWriter(ModuleDefinition module, Stream symbolStream)
			=> module.SymbolReader.GetWriterProvider().GetSymbolWriter(module, symbolStream);
	}
}

class Test
{
	public void Print()
	{
		Console.WriteLine("Test");
	}
}

It works fine when I generate a file but It doesn’t when I try to load it in memory. It fails with the following message: Module was built without symbols; What is the right way to do it?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
jbevaincommented, Mar 17, 2021

This is issue is related to #734 has well. Cecil needs to do a better job at handling filenames for non FileStream scenarios. But I like your fix in the meantime. Thanks!

1reaction
jbevaincommented, Jan 6, 2021

Maybe try to hardcode a file name in there:

https://github.com/jbevain/cecil/blob/master/Mono.Cecil.Cil/PortablePdb.cs#L304

Instead of writer.BaseStream.GetFileName (), as this will return an empty string on a non file based stream.

And see if then the symbols are loaded?

Read more comments on GitHub >

github_iconTop Results From Across the Web

How can I load debug-symbols for a running process?
The best practice is to build the application with debug symbols, keep the resulting binary for debugging, but run strip -g app.debug -o ......
Read more >
Debugging with Symbols - Win32 apps
This article provides a high level overview of how to best use symbols in your debugging process.
Read more >
Tips for working with debug symbols for .NET and ... - YouTube
Increase the efficiency of your debugging by taking full control over debug symbols. These demos explore the finer points of VS Symbol ...
Read more >
Debug using ArcGIS Windows symbol files
Open the Modules window by choosing Debug > Windows > Modules. Locate the module Esri.ArcGISRuntime.dll then right click and choose Load Symbols. Ensure...
Read more >
Files (Debugging with GDB)
Use filename as the program to be debugged. It is read for its symbols and for the contents of pure memory. It is...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found