How to get the value from the byte array object using ICorProfilerInfo2 - clr-profiling-api

I'm using ICorProfilerCallback2 interface to profiler my application. On function enter hook I'm trying to read the value from byte array which is passed as an argument to a function. I've the argument info COR_PRF_FUNCTION_ARGUMENT_INFO from which I can get the starting address of the byte array argument.
If it is a string argument I can use "GetStringLayout" method from ICorProfilerInfo2 interface to get the bufferoffset and stringlengthoffset.
How can I find the offsets for byte array and how to read the values from it?
Where can I find the documents for those?

If you have the ObjectID (or COR_PRF_FUNCTION_ARGUMENT_RANGE) of the argument, you have an easy life (at least for Objects/Arrays, not for Value Types. You have to validate the parameter type using the metadata).
You can use ICorProfilerInfo::GetClassFromObject and ICorProfilerInfo::IsArrayClass to determine if it's an array. If so, IsArrayClass gives you the type of array. Arrays in .Net have a specific layout (I don't think it's in the official docs): It's always 8 bytes for ClassID, 8 bytes for size, and than all the elements, without padding (Note: Objects are stored by ObjectID, just like in other memory regions).
You can also use ICorProfilerInfo2::GetArrayObjectInfo to get the size (need to calculate from dimensions) and the starting address of the objects.
Relevant reads:
https://mattwarren.org/2017/05/08/Arrays-and-the-CLR-a-Very-Special-Relationship/
https://windowsdebugging.wordpress.com/2012/04/24/memorylayoutofarraysx64/

Related

How to declare any-range string element inside an user-defined type in QBasic?

I'm learning QBasic and found an user-defined type example code in a documentation. In this example there's a string element inside an user-defined type, and that string doesn't have a length defined.
However my compiler throws the exception "Expected STRING * on..." for this example. Test-case defining the string length:
TYPE Person
name AS STRING * 4
END TYPE
DIM Matheus AS Person:
Matheus.name = "Matheus":
PRINT Matheus.name:
It logs "Math", expected "Matheus". Is there a way to allow any range for this string?
Note: I'm using QB64 compiler
No, there is not a way to use a variable-length string, even with QB64. You might look into FreeBASIC if you want this feature since it offers it.
TYPE creates a record type with the specified fields, and records have a fixed length. Look at the OPEN ... FOR RANDOM specification:
OPEN Filename$ FOR RANDOM AS #1 [LEN = recordlength%]
recordlength% is determined by getting the LEN of a TYPE variable or a FIELD statement.
If no record length is used in the OPEN statement, the default record size is 128 bytes except for the last record.
A record length cannot exceed 32767 or an error will occur!
TYPE was never intended to contain strings that are dynamically sized. This allows a developer to keep record sizes small. If you had an address book, for example, you wouldn't want people's names to be too large, else the address book wouldn't fit in memory.
QB64 didn't remove that restraint, probably to keep things compatible with older QBASIC code since the original goal was to preserve compatibility.

What about memory layout means that []T cannot be converted to []interface in Go?

So I've been reading these two articles and this answer
Cannot convert []string to []interface {} says that the memory layout needs to be changed.
http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go says that understanding the underlying memory makes answering this question easy, and
http://research.swtch.com/interfaces, explains what is going on under the hood.
But for the life of me I can't think of a reason, in terms of the implementation of interfaces as to why []T cannot be cast to []interface.
So Why?
The article "InterfaceSlice" try to detail:
A variable with type []interface{} is not an interface! It is a slice whose element type happens to be interface{}. But even given this, one might say that the meaning is clear.
Well, is it? A variable with type []interface{} has a specific memory layout, known at compile time.
Each interface{} takes up two words (one word for the type of what is contained, the other word for either the contained data or a pointer to it). As a consequence, a slice with length N and with type []interface{} is backed by a chunk of data that is N*2 words long.
See also "what is the meaning of interface{} in golang?"
This is different than the chunk of data backing a slice with type []MyType and the same length. Its chunk of data will be N*sizeof(MyType) words long.
The result is that you cannot quickly assign something of type []MyType to something of type []interface{}; the data behind them just look different.
"why []string can not be converted to []interface{} in Go" adds a good illustration:
// imagine this is possible
var sliceOfInterface = []interface{}(sliceOfStrings)
// since it's array of interface{} now - we can do anything
// let's put integer into the first position
sliceOfInterface[0] = 1
// sliceOfStrings still points to the same array, and now "one" is replaced by 1
fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!
Read the blog article The Laws of Reflection, section The representation of an interface.
A variable of interface type stores a pair: the concrete value assigned to the variable, and that value's type descriptor. To be more precise, the value is the underlying concrete data item that implements the interface and the type describes the full type of that item.
So if you have a value of []T (a slice of T) where T is not an interface, the elements of such a slice only stores values of type T, but it does not store the type information, it belongs to the slice type.
If you have a value of type []inteface{}, the elements of such a slice holds the concrete values and the type descriptors of those values.
So elements in a []interface{} require more info (more memory) than in a non-interface []T. And if the occupied memory of those 2 slices are not the same, they cannot be just "looked at" differently (looked at as a differnet type). Producing one from the other requires additional work.

How to define a variable length type in postgresql

I try to declare a variable length type which contains a numeric array,
the type looks like
typedef struct MyType {
double count;
double[] lower;
double[] upper;
} MyType;
I find some words in postgresql website as follows:
"To do this, the internal representation must follow the standard layout for variable-length data: the first four bytes must be a char[4] field which is never accessed directly (customarily named vl_len_). You must use SET_VARSIZE() to store the size of the datum in this field and VARSIZE() to retrieve it. The C functions operating on the data type must always be careful to unpack any toasted values they are handed, by using PG_DETOAST_DATUM."
These words confuse me. For example, how to convert the values to toasted values?
Could you give me some examples or some suggestions about how to implement it?
Thanks very much

How to create an Array from Iterable in Scala 2.7.7?

I'm using Scala 2.7.7
I'm experiencing difficulties with access to the documentation, so code snippets would be greate.
Context
I parse an IP address of 4 or 16 bytes in length. I need an array of bytes, to pass into java.net.InetAddress. The result of String.split(separator).map(_.toByte) returns me an instance of Iterable.
I see two ways to solve the problem
use an array of 16 bytes length, fil it from Iterable and return just a part of it, if not all fields are used (Is there a function to fill an array in 2.7.7? How to get the part?).
use a dynamic length container and form an array form it (Which container is suitable?).
Current implementation is published in my other question about memory leaks.
In Scala 2.7, Iterable has a method called copyToArray.
I'd strongly advise you not to use an Array here, unless you have to use a particular library/framework then requires an array.
Normally, you'd be better off with a native Scala type:
String.split(separator).map(_.toByte).toList
//or
String.split(separator).map(_.toByte).toSeq
Update
Assuming that your original string is a delimited list of hostnames, why not just:
val namesStr = "www.sun.com;www.stackoverflow.com;www.scala-tools.com"
val separator = ";"
val addresses = namesStr.split(separator).map(InetAddress.getByName)
That'll give you an iterable of InetAddress instances.

NSCoding and integer arrays

How do you use NSCoding to code (and decode) an array of of ten values of primitive type int? Encode each integer individually (in a for-loop). But what if my array held one million integers? Is there a more satisfying alternative to using a for-loop here?
Edit (after first answer): And decode? (#Justin: I'll then tick your answer.)
If performance is your concern here: CFData/NSData is NSCoding compliant, so just wrap your serialized representation of the array as NSCFData.
edit to detail encoding/decoding:
your array of ints will need to to be converted to a common endian format (depending on the machine's endianness) - e.g. always store it as little or big endian. during encoding, convert it to an array of integers in the specified endianness, which is passed to the NSData object. then pass the NSData representation to the NSCoder instance. at decode, you'll receive an NSData object for the key, you conditionally convert it to the native endianness of the machine when decoding it. one set of byte swapping routines available for OS X and iOS begin with OSSwap*.
alternatively, see -[NSCoder encodeBytes:voidPtr length:numBytes forKey:key]. this routine also requires the client to swap endianness.