getting line numbers of offending code in debug vs release builds - c#

My understanding is that with crash dump of debug build you can get the line number of stack trace and this does not happen with release build. In order to try this, I created a very simple application that crashes.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press any key to continue");
Console.ReadKey();
TestMe(null);
}
static void TestMe(MyClass c)
{
Console.WriteLine(c.Field);
}
}
class MyClass
{
public string Field { get; set; }
}
I created one debug build and one release build. Ran both of these and catpured crash dump via ADPlus. Below are the stack traces for each build. As you can see I am getting the line number in both builds. Obviously difference is that in release build its not reporting call to TestMe method. Any ideas why? Do I need add symbol path to application pdb files in both cases
Debug build
0:000> !CLRStack
OS Thread Id: 0x2398 (0)
Child SP IP Call Site
001eee74 003400db ConsoleApplication1.Program.TestMe(ConsoleApplication1.MyClass)*** WARNING: Unable to verify checksum for ConsoleApplication1.exe
[c:\ConsoleApplication1\ConsoleApplication1\Program.cs # 20]
001eee84 003400a5 ConsoleApplication1.Program.Main(System.String[]) [c:\ConsoleApplication1\ConsoleApplication1\Program.cs # 14]
001ef0c8 6ccb21bb [GCFrame: 001ef0c8]
Release build
0:000> !CLRStack
OS Thread Id: 0x2e40 (0)
Child SP IP Call Site
003bf5f8 772af8c1 [GCFrame: 003bf5f8] Unknown
003bf3b4 002b0098 ConsoleApplication1.Program.Main(System.String[])*** WARNING: Unable to verify checksum for ConsoleApplication1.exe
[c:\ConsoleApplication1\ConsoleApplication1\Program.cs # 14]
003bf5f8 6ccb21bb [GCFrame: 003bf5f8]

In the release build, the JIT compiler is no doubt inlining the method call - that's why the line number is different.

Related

Vs2019.9.2 Raise runtime errors when using Property Pattern for undefined variable and fail compilation and it's expected compilation error

Using Vs 2019.9.2 (or v 2019.9.0):
Create a console net5 application.
Add the next class:
class Class1
{
public void Test1()
{
if (shape is Circle { Radius: >= 100 }) //variable shape is un defined, cause many errors by vs 2019.9.2
{
// this is a huge circle
}
}
}
public class Circle
{
public double Radius { get; init; }
}
You get many error messages (without compilation) at the upper screen under the menu with these common errors:
Feature 'Diagnostic analyzer runner' is currently unavailable due to an internal error. Show Stack Trace
Feature 'CodeLens references' is currently unavailable due to an internal error. Show Stack Trace
Feature 'Semantic classification cache' is currently unavailable due to an internal error. Show Stack Trace
The common error message in Stack Trace:
RPC server exception:
System.InvalidOperationException: Operation is not valid due to the current state of the object.
as shown in the next figure:
and you can't remove these errors, then vs2019 raise the compilation error:
Error MSB6006 "csc.exe" exited with code -2146232797. Vs2019Bug C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\Roslyn\Microsoft.CSharp.Core.targets 71
The line ( with undefined variable shape)
if (shape is Circle { Radius: >= 100 })
cause these errors, and it's expected that vs 2019 raise a compilation error.
Remove the Property Patten check and replace the above line with the next one:
if (shape is Circle ) //cause compilation error as expected
What I missed to avoid the VS2019 runtime error?
I have posted the issue to the Roslyn Project
here
It was reported as a bug and the issue is resolved by Roslyn Team in the next version of Vs 2019.
Thanks to Roslyn team.

Assigning a Functional breakpoint to windows dll/API function call

I am trying to set a breakpoint for whenever a kernel32.dll function is called. Similar to this Get the callstack(s) when a kernel32.dll function is called
I assign a function breakpoint, but after assigning it has the symbol saying they will never be hit and they don't. I need to do it in x86 but can't even get this simple 64 bit one to work.
I did check "Microsoft Symbol Servers" in Tools->Options/Debugging/Symbols but the cache directory is still empty. I think this is the problem but not sure. How do I make sure the dll debug symbols are loaded correctly?
Example code.
using System;
using System.Runtime.InteropServices;
namespace DebugAPI
{
class Program
{
[DllImport("kernel32.dll")]
public static extern System.UInt32 GetCurrentProcessorNumber();
static void Main(string[] args)
{
var num = GetCurrentProcessorNumber();
Console.WriteLine("Proc# " + num.ToString());
}
}
}
I tried two ways of doing the Function Breakpoints for 64bit.
Kernel32!GetCurrentProcessorNumber
{,,kernel32.dll}GetCurrentProcessorNumber
For x86 I tried the following
{,,kernel32.dll}_GetCurrentProcessorNumber#4 //Not sure if #4 is correct
For the record here are the full steps for setting up the breakpoints using GetCorrent ProcessorNumber as an example. Note VS2017 seems to have a bug with x64 platform target. Must be x86 or anycpu.
In Solution Explorere right click "YourProject"->Properties->Debug->"Enable native code debugging" = checked
In the Main Menu Debug->Options->Debugging->Symbols->"Microsoft Symbol Servers" = checked. & assign a cache path
Add Functional Breakpoint Debug->New Breakpoint->Functional Breakpoint.
[Name Options]
[x86 & x64] - Function Name = Kernel32!GetCurrentProcessorNumber Language = All
[x86] Function Name = {,,kernel32.dll)GetCurrentProcessorNumber Language = All
[x86] Function Name = _NtGetCurrentProcessorNumber#0 Language = All (Reference for # after # https://stackoverflow.com/a/40031574/1132334 credit - dlatikay)
Note : First time debug it takes a while to download the symbols.

Go to library to C# | BadImageFormatException

I would like to create a library out of go-code and use it inside a C# winforms project.
For the error scroll to the bottom.
Setup
GO 1.10.2
tdm-gcc-5.1.0-3
Windows 10 / x64
Go-project called exprt
What I've tried
I've created a minimal go-tool that creates a file in the working-dir:
package main
import (
"os"
"C"
)
func main() {
// nothing here
}
//export Test
func Test() {
os.OpenFile("created_file.txt", os.O_RDONLY|os.O_CREATE, 0666);
}
The next steps were taken from Building a dll with Go 1.7.
I've then compiled to c-archive with the following command: go build -buildmode=c-archive which gives me exprt.a and exprt.h.
After that I've created a file called goDLL.c (1:1 as in the link above) and inserted this code:
#include <stdio.h>
#include "exprt.h"
// force gcc to link in go runtime (may be a better solution than this)
void dummy() {
Test();
}
int main() {
}
Lastly I've run this command to create my final dll:
gcc -shared -pthread -o goDLL.dll goDLL.c exprt.a -lWinMM -lntdll -lWS2_32
which gave me "goDLL.dll".
My problem
In C# I've created a winforms-project with 1 button that calls this declared function (copied the dll to the debug-folder):
[DllImport("goDLL.dll")]
private static extern void Test();
Error
System.BadImageFormatException: "An attempt was made to load a program with an incorrect format. (HRESULT: 0x8007000B)"
Sorry for that big block of text but this was the most minimal test I could think off.
I appreciate every help in here.
Well, in the given answer here https://social.msdn.microsoft.com/Forums/vstudio/en-US/ee3df896-1d33-451b-a8a3-716294b44b2b/socket-programming-on-64bit-machine?forum=vclanguage there is written:
The implementation is in a file called ws2_32.dll and there are 32-bit and 64-bit versions of the DLL in 64-bit Windows.
So the build as described in my question is correct.
Solution
The C#-Project has to be explicitly set to x64. AnyCPU won't work and throw the error shown in the question above.
Everything is working now. I'm leaving the question and answer as this is a full explanation of how to get go-code running out of C#.

StyleCop Analyzers rule SA1515 violation output only in Output Window but not in Error List Window

I have installed StyleCop.Analyzers nuget (it's version 1.0.0) and I have configured SA1515 (Single comments must be preceded by blank line) to error on violation.
The following code however
namespace ConsoleApplication6
{
class Program
{
static void Main(string[] args)
{
int x = 2;
/// my comment
int y = 3;
}
}
}
does only show the violation in the Ouput Window as
ConsoleApplication6\Program.cs(8,7,8,9): error SA1515: Single-line comment must be preceded by blank linelists the error
but there are no squiggles and no entries in the Error Window. Changing the /// to // makes the error appear in the error list immediately.
Is there are way to debug this in order to find the buggy spot? I have opened the source code I got from GitHub in Visual Studio, set a break point on the one context.ReportDiagnostic call in that rule class, set to start another VS instance on debug start, opened the ConsoleApplication6 in there and never got a break point hit.

How do I get filenames and line numbers in c# stack traces running in edge.js on OSX

This is specifically about getting line numbers in stack traces when running c# under edge.js.
Given this C# source file (test.cs)
using System;
using System.Threading.Tasks;
namespace test {
public class Startup {
public async Task<object> Invoke(dynamic input) {
try {
throw new Exception("some error");
} catch(Exception e) {
Console.WriteLine(e);
}
return null;
}
}
}
I'm building a .dll (and .dll.mdb) with the command:
mcs -debug -target:library -out:test.dll test.cs
And running with this edge.js script:
var edge = require('edge');
var myfunc = edge.func({
assemblyFile: __dirname + '/test.dll'
});
myfunc(true, function(err, result) { });
The stack trace in the output has no filename or line numbers:
System.Exception: some error
at test.Startup+<Invoke>c__async0.MoveNext () [0x00000] in <filename unknown>:0
Is there a way to get filenames and line numbers in the stack trace instead of <filename unknown>:0 ?
From the command line, mono must be run using the --debug argument in order to get line numbers. If that's the case here, then this question may boil down to "How do i pass arguments to CLR from edge.js?"
Versions: node.js:v0.10.39, mcs/mono:4.0.4.0, edge.js:4.0.0
[Edit]
I found you can get command line arguments into mono from edge by setting the environment variable MONO_ENV_OPTIONS. Unfortunately this doesn't work with --debug.
After researching this, seems like edge does not provide a way to activate debugging in the embedded mono, you need to modify and build edge yourself to accomplish it. It is a quick process, though, once you figure it out:
1. Install edge for your project normally with:
npm install edge
I did follow the steps for building on OSX, but it's not necessary.
2. Change node_modules/edge/src/mono/monoembedding.cpp to include mono-debug.h and call mono_debug_init within MonoEmbedding::Initialize. The file should look something like this:
#include <dlfcn.h>
#include <limits.h>
#include <libgen.h>
#include "edge.h"
#include "mono/metadata/mono-debug.h" //This is new
#include "mono/metadata/assembly.h"
#include "mono/metadata/mono-config.h"
#include "mono/jit/jit.h"
MonoAssembly* MonoEmbedding::assembly = NULL;
void MonoEmbedding::Initialize()
{
...
//This is new. Must be called before 'mono_jit_init'
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
mono_config_parse (NULL);
mono_jit_init (fullPath);
...
}
3. From node_modules/edge/, build edge using:
node-gyp configure build
You might get an error similar to:
Error: Cannot find module 'nan'
In that case run npm install --save nan, that should fix it.
4. Run your test again. Output is now:
System.Exception: some error
at test.Startup+<Invoke>c__async0.MoveNext ()
[0x00019] in /Developer/tests/so/test.cs:8

Categories