I am writing a jvmti agent for java programs.I am trying to read objects on the stack.Using jnienv pointer received on VMinit/vmstart event.
I succeeded in reading objects upon methodexit event using the foll:
get varaible (slot) from getlocalvariableentry() ;
from the variable signature use jni functions to get object, use getlocalobject function for a reference object/subclass of object.Then if its a subclass of object; jni::getobjectclass(); use returned class and obtain fields in the class;
using getclassfields(); then get field signature from getfieldname(); then call appropriate function for the field as per its signature eg getintfield() for int field.
Howver once I try this upon Objects created within a try block within the function for which methodexit event is raised; I get a crash(SIGSEGV) everytime at Getobjectclass() .Is this because the object has gotten destroyed being out of scope; If so how to read values of variables in a try block of a function at function exit.
obtain crash when upon reading a jobject for Integer (from localvariabletableentry) object , I call getintfield() for its int field member MIN_VALUE which is its first member.If I just try to read member "value" of Integer class then calling getintfield() does not crash.
Is this crash because Im trying to read a static final member of a class ie. member MIN_VALUE Of integer class.
How to come around this and avoid the crashes?
Related
I am trying to log field writes with bytebuddy. After reading some earlier posts, I started using MemberSubstitution and got something going using the following code:
private static Method FIELD_INTERCEPTOR = // reflective reference to interceptFieldWrite
AsmVisitorWrapper VISITOR = MemberSubstitution.relaxed()
.field(ElementMatchers.any())
.onWrite()
.replaceWith(FIELD_INTERCEPTOR)
.on(ElementMatchers.isMethod());
..
public static void interceptFieldWrite(Object object,Object value) {
System.out.println("intercepted field write in object " + object + " , attempt to set value to " + value);
}
..
The part I am struggling with is how to pass a reference to the field for which the access is intercepted to interceptFieldWrite (as string or instance of Field). If possible I would of course like to avoid reflection completely. I don't actually want to completely substitute field access, but just want to add a method with some checks just before it takes place. Is there a feature in bytebuddy to do this, or do I have to use something more low-level than ASM to achieve this ?
Byte Buddy offers this but you will have to compose your own StackManipulations to do so. The mechanism in MemberSubstitution is called replaceWithChain. Here you specify Steps where each step can do what you intend:
invoke a method via MethodInvocation.
write a field via FieldAccessor.
You will have to load the arguments to the method call and the field access prior to using the above stack manipulations via the MethodVariableAccess where the targeted element's offsets are represented by offsets.
In your case, this would require to read the target instance via
MethodVaribaleAccess.of(parameters.get(0)).loadFrom(offsets.get(0));
MethodVaribaleAccess.of(parameters.get(1)).loadFrom(offsets.get(1));
and the to execute the method or field write in question. The targeted field will be passed as target, you can cast it to FieldDescription if you only ever intercept fields.
Make sure you only intercept non-static fields where the this instance will not be passed.
I implemented an extension method on Integer (this is a simplified example that also shows the error)
<Extension()>
Public Function IsPositive(ByVal item As Integer) As Boolean
Return item > 0
End Function
I then try to call the extension method on a datarow's item:
Dim dtMyTable As DataTable
dtMyTable = GetInfoFromDatabase()
If dtMyTable.Rows(0).Item("nCount").IsPositive() Then
This gives me the exception:
Public member 'IsPostive' on type 'Integer' not found.
I assume this is because dtMyTable.Rows(0).Item("nCount") is actually an object, not an integer. The exception seems to understand that that isn't the case, so I'm not sure why that's different, but it is.
However, if I try to call the same method as if it's just a regular method, it works without complaint
If IsPositive(dtMyTable.Rows(0).Item("nCount")) Then
I would rather call it the former way. I know it's possible to just save the value to a variable and then call the extension on that variable, but that seems like a needless extra step.
Is there any way to get the former method to work without adding an extra variable assignment every time I need to call it, or changing the extension method to work on Objects?
below code is c#
ctx.CreateStreamResponse(stream => new Session(_Sessions, stream).Process(),"video/mp4");
and i need to this code as VB.NET code. am converting as below
ctx.CreateStreamResponse(Function(stream) New Session(_Sessions, stream).Process(), "video/mp4")
But getting error
overload resolution failed because no accessible
"CreateStreamResponse" can be called with these arguments.
CreateStreamResponse needs 2 parameters
Stream (as my sample Function(stream) New Session(_Sessions, stream).Process())
content type (as my sample "video/mp4")
Anyone can help me, please
I believe the issue seems to be that the method which you pass into CreateStreamResponse should be a Sub not a Function. i.e:
ctx.CreateStreamResponse(Sub(stream) New Session(_Sessions, stream).Process(), "video/mp4")
CreateStreamResponse takes an Action(Of Stream) delegate as the first argument and a contentType of String as the second argument.
Thus you need to use Sub rather than a Function as in this case an Action delegate can only encapsulate methods that return void (sub procedures). Also, ensure that the Process method being invoked is also a Sub procedure.
If the problem persists then as suggested by Microsoft docs:
Review all the overloads for the method and determine which one you
want to call.
In your calling statement, make the data types of the arguments
match the data types of the parameters defined for the desired
overload. You might have to use the CType Function to convert one or
more data types to the defined types.
for more information see here
I work with the registry and use the function RegNotifyChangeKeyValue. The first option requires registry key handle (HKEY), but I have RegistryKey, from which I can get SafeRegistryKey (key->Handle).
RegistryKey^ key = myKey;
RegNotifyChangeKeyValue(key->Handle, true, dwFilter, events[i], true);
Error: "argument of type "Microsoft::Win32::SafeHandles::SafeRegistryHandle" is incompatible with parameter of type "HKEY""
How do I get HKEY?
A conversion is required to get from the wrapped IntPtr in the safe-handle class to the native handle. It looks like this:
HKEY handle = (HKEY)key->Handle->DangerousGetHandle().ToPointer();
You do get to fret over the word "Dangerous" in the method name, it is aptly named. There is nothing that the CLR can do to ensure that the handle stays valid until you no longer need the change notifications. It is now your job to ensure that the key object reference stays visible and the garbage collector won't collect it too early.
It cannot be a local variable, it could be a member of a class but that in turn requires the class object to stay referenced. Storing it in a static variable is the safest way, calling GCHandle::Alloc() is the next best way, maybe you need gcroot<>. There's no context in the question to make the call.
The program is used in the context of MPI.It's a MPI implementation of fortran.
I declare an array within a module.like
module var
real,save ::arr(8)
end module
Then use a subroutine like init to initialize the array arr.
In the main program unit,first call init to initialize the array arr.And then call another
subroutine like algo to do some computations.At the beginning of subroutine algo,the value of arr is correct.During the process of computation,the value of arr changed weirdly on some processors though there is no code changing the value of arr while on the other processors the value is correct.
I check the code and I am pretty sure no code change the value of arr during computation.
By the way,numbers of variables declared within the module var are numerous.
Thanks for all of you who give suggestions.The error is due to the access of array element out
of boundary.In my program there is a line of code accessing the index 0 element in array like
arr(0)=... which is beyond the range of fortran array.And this code leads to the value of another variable in the module to be changed which is quite unexpected to me.arr(0)=.. leads to the change of another variable like parm defined in the module.
Since you are using MPI, you must also broadcast the variable to all processors if the initialization is being done only on one processor