LoadRunner AccessViolationException when invoking web.url in C# - c#

What's the correct syntax to invoke a HTTP Get using the LoadRunner API (VUGEN 9.52.0.0) in C#? The following generates an AccessViolationException:
LoadRunner.WebApi web = new LoadRunner.WebApi();
web.url("GoToMyService", "http://path/to/my/service/", new string[0], "LAST");
Exception thrown by call to web.url:
Error: Action.cs(25): System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at LoadRunner.WebApiClass.url(String name, String urladdr, Object options, Object extrares)
at Script.VuserClass.Action() in h:\Personal\_projects\LoadTest\Action.cs:line 25

One option, which isn't really in the spirit of LoadRunner, is to skip using the LoadRunner API and just use the System.Net APIs:
WebResponse response = HttpWebRequest.Create("http://path/to/my/service/").GetResponse();

You are engaging in an ethically problematic activity for a performance tester: You do not point a loaded gun at something that you do not own, manage or control. LoadRunner is a loaded gun and I am ~~~assuming~~ you don't work for google. So, just don't

Related

Runtime casting of COM objects in C#

I am working on a application which needs to communicate via COM interface with multiple CAD applications (not in the same time). I want to have nice and reusable code, but I came across problems with type casting of COM objects when I made generic application handle getter method.
What I tried so far:
This is the attempt I would like the most if it worked.
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
//Here under Dynamic View/Message there is already an error
// Message = "Element not found. (Exception from HRESULT: 0x8002802B (TYPE_E_ELEMENTNOTFOUND))"
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = (TCadAppType)Marshal.GetActiveObject(cadVersion.Value);
//Following 2 lines of code are for testing purposes only, i am testing with Solidworks API
AssemblyDoc Assembly;
//The exception is thrown when I try to access some method from the Solidworks API
Assembly = (AssemblyDoc)cadApp.OpenDoc6("some parametras...");
}
Attempt using Convert class
// Another attempt using Convert class
public static TCadAppType CadApp<TCadAppType>()
{
dynamic cadApp = default(TCadAppType);
// cadVersion.Value evaluates to "SldWorks.Application"
cadApp = Marshal.GetActiveObject(cadVersion.Value);
cadApp = Convert.ChangeType(cadApp, typeof(SldWorks.SldWorks));
// Exception is thrown with the following message:
// Message = "Object must implement IConvertible."
}
I really thought that I am on the right track, since there is an article on Microsoft Docs website explaining how dynamic can help you with com interopt: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/using-type-dynamic#com-interop
Any ideas how I can do this runtime casting a keep my code as reusable as possible?
My software setup:
Win 10
Project is targeted for .NET 4.7.2
First Tests are with Solidworks 2019
Turns out that the my coding attempt 1 was valid c# code indeed.
I tried it using with Autodesk Inventor, and it works.
So the only thing left for me is to conclude that this is some bug from Solidworks and their COM interfacing.
Thank you Optional Option for your interest in the topic.

How do I get CallerFilePath and CallerLineNumber without using the CallerInfo attributes?

For my log4net solution, I have an API wrapper that uses the CallerInfo attributes, e.g.
public void Write(string message,
[CallerMemberName] string memberName = "",
[CallerFilePath] string filePath = "",
[CallerLineNumber] int lineNumber = 0)
However, I am also using Unity Interception so that I can perform trace logging of the before/after responses, e.g. using ICallHandler like below in the Invoke method.
public class TraceCallHandler : ICallHandler
{
...
public IMethodReturn Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext)
{
//---- Trace method inputs
this.LogInfoBeforeInvoke(input);
//---- invoking the target method
InvokeHandlerDelegate next = getNext();
IMethodReturn methodReturn = next(input, getNext);
//---- invoking the target method
this.LogInfoAfterInvoke(methodReturn.ReturnValue);
}
}
Note: The above code is in no way complete/correct... but just wanted to show you what I was doing for Unity Interception.
My question / challenge is this:
when I eventually call log.Write(...), I want the target's caller info, not my TraceCallHandler info.
e.g. for method name, I can do this:
string methodName = input.MethodBase.Name;
How do I get the Caller's File Path and Caller's Line Number? Is it even possible to do via reflection?
Thanks!
Yes, you can get these using reflection:
var sf = new System.Diagnostics.StackTrace(1).GetFrame(0);
Console.WriteLine(" File: {0}", sf.GetFileName());
Console.WriteLine(" Line Number: {0}", sf.GetFileLineNumber());
// Note that the column number defaults to zero
// when not initialized.
Console.WriteLine(" Column Number: {0}", sf.GetFileColumnNumber());
However as it says clearly in the documentation:
StackFrame information will be most informative with Debug build
configurations. By default, Debug builds include debug symbols, while
Release builds do not. The debug symbols contain most of the file,
method name, line number, and column information used in constructing
StackFrame objects.
So if all you want this for is debugging, then enable it in debug builds and log away. In Release builds though it will be at best unhelpful and at worst downright misleading as apart from the symbol considerations above the compiler will aggressively inline methods and reorder things and generally mess with your stuff.
I just ran across this issue and thought I would share what I learned. First, when you include [CallerFilePath] in a method argument a side effect is that the full path of the file, including any user identifiable data, will be included in your .exe. I created a simple program with one method. I created an exe. I then added a [CallerFilePath] attribute to the test function. When I compared the results of strings.exe (from sysinternals), the one with the attribute differed in that it included the full path of my source file.
c:\users\<my name>\documents\visual studio 2015\Projects\TestCallerAttribute\TestCallerAttribute\Program.cs
The answer above by stuartd is correct in that you will not be able to get the data you want from the stack trace in a release build.
There is a solution to getting strong data however: Event Tracing for Windows. From msdn: "Event Tracing for Windows (ETW) is an efficient kernel-level tracing facility that lets you log kernel or application-defined events to a log file. You can consume the events in real time or from a log file and use them to debug an application or to determine where performance issues are occurring in the application."
This is not a quick solution. There is work in setting up the events and the listeners to get the provenance you need. The long term payoff is strong.

Determining interop function caller

I'm exposing a C# class to COM using these attributes:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[GuidAttribute("2325EBEB-DB5F-4D29-B220-64845379D9C5")]
[ComSourceInterfaces(typeof(WrapperEvents))]
in this class I have a function:
public void shutdownService()
This function is meant to be called just once from a VB6 client via COM Interop. Everything works fine. But somehow, it's being called more than once. My C# codes doesn't call this function directly. So I'm guessing the problem is in VB6 code. Unfortunately, that's not what the VB6 team thinks.
Is there a way to determine the caller of this function, ie. from my C#code or the VB6 code?
Right now I'm using a simple function to get the stacktrace:
public void LogStack()
{
var trace = new System.Diagnostics.StackTrace();
foreach (var frame in trace.GetFrames())
{
var method = frame.GetMethod();
if (method.Name.Equals("LogStack")) continue;
logger.Debug(string.Format("LogStack: {0}::{1}",
method.ReflectedType != null ? method.ReflectedType.Name : string.Empty, method.Name));
}
}
Obviously, I got somthing like this on the log:
2011-12-23 08:28:40,067 1 DEBUG (null) LogStack: Service::shutdownService
Since the only line of LogStack is the COM exposed function, I assume it's being called from vb6. But that's not enough proof for the VB6 team. Any idea how to really prove where function ?
You can try several things:
set a breakpoint in your code to trigger the debugger, then look at the call stack.
You could do an application dump here from visual studio and send it to them or screenshot the stack.
ex. Debugger.Break
http://www.netsplore.com/PublicPortal/blog.aspx?EntryID=12
Dump with "Savre Dump As"
http://msdn.microsoft.com/en-us/library/d5zhxt22.aspx
Use the com tracing
from a system level see
http://support.microsoft.com/kb/926098
I also recall a tool being installed with visual studio 6 do to this as well

WinDbg and .Net x64 Assembly : Step-By-Step Walkthrough for hitting a breakpoint in a C# source

I am having very hard times using WinDbg to track a simple object reference in a C# Forms App.
I have found a very nice tuto by Chris Lovett : GCRoot Demo on using "SOS" in VS' Immediate Window
Unfortunately, I am debugging an x64 App and recompiling my App into 32-bit will bias the test conditions I am willing to recreate. Trying to load SOS in an x64 Assembly results, as expected, in the following error :
Error during command: extension C:\Windows\Microsoft.NET\Framework64\v4.0.30319\sos.dll could not load (error 193)
So, as WinDbg seems to manage x64, that's the way to go for me. However, getting it to work with managed code is not a straightforward task.
Putting a simple breakpoint into the attached source results, unsurprisingly, into the following error :
Unable to insert breakpoint 0 at 00000000 010e000f, Win32 error 0n998
"Invalid access to memory location."
This is consistent with the guidelines given by Naveen Srinivasan.on his Blog
However, when I try to use the ” sxe ld” / “.loadby sos” / ”.load sosex" workarounds suggested in that same web page, I get the following error :
The call to LoadLibrary(sos) failed, Win32 error 0n2
The system cannot find the file specified.
So I guess the latter commands are also SOS-related
I have also tried to follow an older post from Eran Sandler which explains exactly how to proceed to set a breakpoint in WinDbg for Managed Code. But I am suspecting the name2ee command he is using to be "SOS" specific, thus making it rather unusable in my case (I am getting same kind of LoadLibrary error).
I am really confused and helpless here. I feel I am bumping on walls whatever direction I take. I am two inches far from giving up and recompiling the whole App into 32-bit to debug it, as I've already lost almost 2 working days on this.
All this is only the first step towards what I want to achieve, which is to track all the references to a "Trackee" object in a more complex App, using gcroot.
Than you for your help.
Dummy Sample code : DebugTest.cs :
namespace DebugTest
{
public partial class Form1 : Form
{
String Trackee;
public Form1()
{
InitializeComponent();
Trackee = "Where is Charlie";
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = Trackee; // << Trying to put a breakpoint here
}
}
}
ANSWER : Walkthrough
1 - "loadby sos.dll clr" makes it possible to call all SOS stuff. (including "name2ee" command to follow Eran Sandler's steps.)
2 - The following command puts a breakpoint efficiently into the Managed code of some method. Example:
!bpmd DebugTEst.exe DebugTest.Form1.button1_Click
3 - I am still unable to have a real visual debugger behavior as break point is hit logically as shown in the command window, but not visually in source window.
4 - By affecting to Trackee a specific Type (MyString, for ex.) I was able to track the Object's adress using !DumpHeap -type myString
which give the following ouput :
Address MT Size
0000000002bd33e0 000007ff000581d0 24
5 - Then after performing a load vgcroot and !vgcroot 0000000002bd33e0 C:\graph.dgml I was able to find and visualize all the references to my Trackee.

how to release object from thid party dll?

i'm developing a program to convert RTF to html
i'm using the DLLs found here
http://www.codeproject.com/KB/recipes/RtfConverter.aspx?fid=1458864&df=90&mpp=25&noise=3&sort=Position&view=Quick&select=3427424&fr=1#xx0xx
this dll saves a jpg file from html to a specific folder,
when i run the program, it cinverts the rtf for the first time and saves the images to the folder perfectly
but when i try to convert it again i hace this error
"error a generic error occured in GDI+"
i think this dll use SaveImage method and to avoid this you must release the Image object you created but i can't modify the DLL,
is there is any way to release the object i've created from this dll?
this is my code
RtfVisualImageAdapter imageAdapter = new RtfVisualImageAdapter(
#Application.StartupPath + "\\Program Data\\temp\\{0}{1}",
System.Drawing.Imaging.ImageFormat.Jpeg);
RtfImageConvertSettings imageConvertSettings =
new RtfImageConvertSettings(imageAdapter);
RtfImageConverter imageConverter = new RtfImageConverter(imageConvertSettings);
try
{
IRtfDocument rtfDocument = RtfInterpreterTool.BuildDoc(
ConversionText, imageConverter);
RtfHtmlConverter htmlConverter = new RtfHtmlConverter(rtfDocument);
htmlConverter.Settings.ConvertVisualHyperlinks = true;
htmlConverter.Settings.UseNonBreakingSpaces = true;
this.richTextBoxPrintCtrl2.Text = htmlConverter.Convert();
}
catch (Exception exception)
{
MessageBox.Show(this, "Error " + exception.Message, this.Text,
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
The code is sloppy, it doesn't call the Dispose() method on the bitmap after saving it. That keeps a lock on the file, GDI+ uses a memory-mapped file to avoid putting pressure on the paging file. Important because bitmaps can be quite large. Trying to save to the same file again fails because of the lock. GDI+ exception messages are notoriously sloppy as well.
I think the bug is located in Interpreter\Converter\Image\RtfImageConverter.cs, SaveImage() method. The "convertedImage" bitmap doesn't get disposed. Note that the Graphics object in that same method doesn't get disposed either. Fix it by wrapping them with the using statement.
Run this code through FxCop to catch similar mistakes. And ask yourself if you really want to maintain code like this.
If something implements IDisposable, you can call its Dispose() method. Objects are eligible for garbage collection as soon as they go out of scope so you might also try calling GC.Collect() after there are no more references to the object you want "released."
As Max sez. Or better use the using construct. NEVER call GC.Collect unless you are dead sure by doing so you'll free a few GB or RAM!
Since you have the source code you could examine it and figure out where it keeps a reference and make sure it's released.
If you cannot figure out where to do this you could load the code up in a separate AppDomain, and execute your code there. When you are finished you can unload the AppDomain, and your application will release any objects. Then recreate the AppDomain for the next run.
But I would try to spend some time figuring out the real issue before using AppDomains.
And another thing. Do you get the GDI error when you execute the same file twice, or two different files in succession? It could be that it fails to load the image of the second file and gives you the error.

Categories