ASM: How to find the type of object contained in ALOAD - bytecode

Let us Consider I have an AbstractInsnNode which is of type ALOAD.
This ALOAD contains an Exception object, while referring the bytecode of the class file. I want to know the desc of the ALOAD using ASM java.
Using LocalVariableNode,(What I did was) I run through the methodNode and found the localvariables name and desc. But Dont know to associate with the corresponding ALOAD.
for ( Object a: methodnode.localVariables) {
LocalVariableNode lvn = (LocalVariableNode)a;
System.out.println(lvn.desc);
}
if ((abstractNode.getOpcode() == Constant.ALOAD)) {
//do Something to check the desc of the ALOAD
return;
}
Please help me out in this.

An ALOAD instruction includes a numeric argument which tells which local variable it loads. Once we have that, we then look in methodnode.localVariables (that you were already printing on screen) to find the correct one.
So one way to go about this to first find out which class represents ALOAD instructions. You can do a google search like "aload extends abstractinsnnode site:asm.ow2.io" to find the *InsnNode to use. The answer for ALOAD is VarInsnNode. It surely enough contains a field int var which holds the local variable number that it loads. It must match the int index field in the LocalVariableNode list. However the same index might be reused for different purposes inside the same method, so you also need to verify that your instruction is between the LabelNode instructions indicated by LabelNode start and LabelNode end instructions in the LocalVariableNode as well. Easiest way to do so is to just use the BasicAnalyer as recommended by #Holger in his comment to the answer by #Antimony. So you get the associated Frame object for your VarInsnNode and do frame.getStack(((VarInsnNode) abstractNode).var) to get the desc of the variable for the ALOAD instruction.

Java bytecode is implicitly typed, so there's no direct way to find the types of values in bytecode. You have to do data flow analysis to find where the value was created and get the type that way. If the class has stack maps, then you just need to trace it back to the previous stack map, but it will still require a bunch of work.

Related

What is the meaning of MAKEINTRESOURCE((id>>4)+1)?

I am trying to mimic the behavior of CString::LoadString(HINSTANCE hInst, DWORD id, WORD langID) without introducing a dependency on MFC into my app. So I walked through the source. The first thing it does is to immediately call AtlGetStringResourceImage(hInst, id, langID), and then this in turn contains the following line of code:
hResource = ::FindResourceExW(hInst, (LPWSTR)RT_STRING, MAKEINTRESOURCEW((id>>4)+1), langID);
(It's not verbatim like this, but I trimmed out some unimportant stuff).
What is the meaning of shifting the ID by 4 and adding 1? According to the documentation of FindResourceEx, you should pass in MAKEINTRESOURCE(id), and I can't find any example code that is manipulating the id before passing it to MAKEINTRESOURCE. At the same time, if I make my code call MAKEINTRESOURCE(id) then it doesn't work and FindResourceEx returns null, whereas if I use the above shift + add, then it does work.
Can anyone explain this?
From the STRINGTABLE resource documentation:
RC allocates 16 strings per section and uses the identifier value to determine which section is to contain the string. Strings whose identifiers differ only in the bottom 4 bits are placed in the same section.
The code you are curious about locates the section a given string identifier is stored in by ignoring the low 4 bits.

Type mismatch error while reading lotus notes document in vb6

Am trying to read the lotus notes document using VB6.I can able to read the values of the but suddenly type mismatch error is throwed.When i reintialise the vb6 variable it works but stops after certain point.
ex; address field in lotus notes
lsaddress=ImsField(doc.address)
private function ImsField(pValue)
ImsField=pValue(0)
end function
Like this I am reading the remaining fields but at certain point the runtime error "13" type mismatch error throwed.
I have to manually reintialize by
set doc=view.getdocumentbykey(doclist)
The type mismatch error occurs for a certain field. The issue should be a data type incompatibility. Try to figure out which field causes the error.
Use GetItemValue() instead of short notation for accessing fields and don't use ImsField():
lsaddress=doc.GetItemValue("address")(0)
The type mismatch is occurring because you are encountering a case where pValue is not an array. That will occur when you attempt to reference a NotesItem that does not exist. I.e., doc.MissingItem.
You should not use the shorthand notation doc.itemName. It is convenient, but it leads to sloppy coding. You should use getItemValue as everyone else is suggesting, and also you should check to see if the NotesItem exists. I.e.,
if doc.hasItem("myItem") then
lsaddress=doc.getItemValue("myItem")(0)
end if
Notes and Domino are schema-less. There are no data integrity checks other than what you write yourself. You may think that the item always has to be there, but the truth is that there is nothing that will ever guarantee that, so it is always up to you to write your code so that it doesn't assume anything.
BTW: There are other checks that you might want to perform besides just whether or not the field exists. You might want to check the field's type as well, but to do that requires going one more level up the object chain and using getFirstItem instead of getItemValue, which I'm not going to get into here. And the reason, once again, is that Notes and Domino are schema-less. You might think that a given item must always be a text list, but all it takes is someone writing sloppy code in an one-time fix-it agent and you could end up having a document in which that item is numeric!
Checking your fields is actually a good reason (sometimes) to encapsulate your field access in a function, much like the way you have attempted to do. The reason I added "sometimes" above is that your code's behavior for a missing field isn't necessarily always going to be the same, but for cases where you just want to return a default value when the field doesn't exist you can use something like this:
lsaddress ImsField("address","")
private function ImsField(fieldName,defaultValue)
if doc.hasItem(fieldName) then
lsaddress=doc.getItemValue(fieldName)(0)
else
lsaddress=defaultValue
end if
end function
Type mismatch comes,
When you try to set values from one kind of datatype variable to different datatype of another variable.
Eg:-
dim x as String
Dim z as variant
z= Split("Test:XXX",":")
x=z
The above will through the error what you mentioned.
So check the below code...
lsaddress = ImsField(doc.address)
What is the datatype of lsaddress?
What is the return type of ImsField(doc.address)?
If the above function parameter is a string, then you should pass the parameter like (doc.address(0))

Add extra database field to blogengine.net

I have added an extra field in the Pages table that I call VirtualPath. This is so that I can have virtual paths to my pages.
In the code I add "VirtualPath" as an extra parameter to the CommandText which means that there will be 14 elements to pick from the database. I duplicate the routine to grep the actual value:
if (!rdr.isDbNull(14))
{
page.VirtualPath = rdr.GetString(14);
}
The problem is that the it never enters the if-statement. When I step the code and I arrive at the !rdr.isDbNull(14)-row and do step-in I see that the DBHelper makes a dispose somehow...
My question is: Is there somewhere else I have to do a change to add an extra parameter like this? Or, does anyone have an idea of what I do wrong. And yes, I have entered values to the VirtualPath-field in the database so it should not be null.
If there are 14 elements to pick from the table, the 14th should be referenced by index 13 (zero-based index).

How does a DataObjects::SQLError object's .code correspond to the error issued by the database?

So I'm doing some business logic and want to run some code that goes like
select id from blah where foo = 1234 for update nolock
This code throws a DataMapper::SQLError when the corresponding row in blah is locked. This is desirable behavior; I would like to catch this error and use it to inform my application logic. But I want to re-throw any other SQL errors, because they're different than the case I'm programming for, and catching them in the same way would be wrong.
The error object returned has a string error message, and a numeric code (50463045). It seems like comparing on the numeric code would be great, but I don't want to embed the constant 50463045 in my code without some modicum of understanding of how the heck it was determined. Notably, the Postgres manual suggests that the error code for this state is 55P03, and that doesn't seem to be the same thing. I don't have any idea how much I can trust this magic number, and how to determine it except for experimentally, so I'm not really comfortable with using it.
How is the error code determined?
The Internet was distressingly unhelpful, since searching for stuff about DataObjects SQL errors seems to mostly return problems with other software raising the errors, not information on the errors themselves... but after locating the right source code and browsing around through the source code I finally located do_postgres.c:
void do_postgres_raise_error(VALUE self, PGresult *result, VALUE query) {
const char *message = PQresultErrorMessage(result);
char *sql_state = PQresultErrorField(result, PG_DIAG_SQLSTATE);
int postgres_errno = MAKE_SQLSTATE(sql_state[0], sql_state[1], sql_state[2], sql_state[3], sql_state[4]);
PQclear(result);
data_objects_raise_error(self, do_postgres_errors, postgres_errno, message, query, rb_str_new2(sql_state));
}
Notice how a 5-character state is passed to MAKE_SQLSTATE... and then also passed to data_objects_raise_error itself. I couldn't track down where MAKE_SQLSTATE is defined to figure out what crazy manipulations are going on to make this integer, but it appears I can just use the error object's .sqlstate property directly, and make my condition e.sqlstate == '55P03'.

How to get name of the bit field referenced by BIT_FIELD_REF?

I want to get the name of the field with which it was declared from GENERIC representation. I have a BIT_FIELD_REF tree and it's DECL_NAME is zero. For example,
struct {
int a;
unsigned b:1;
} s;
...
if (s.b)
...
For s.b I'll get a BIT_FIELD_REF and there's no obvious way to get the “b”, which is the original name of the field. How to do it?
Try call debug_c_tree (tree_var) or call debug_tree (tree_var) from GDB, and see if that knows the name. If it does, reverse engineer the pretty-printer.
What exactly did I do: investigating stuff in tree-dump.c I ended up understanding that names of the bit fields where they're known were coming from struct's DIEs and were hard to track.
Then I decided to get the name from the BIT_FIELD_REF argument 0 (reference to structure) type, which is RECORD_TYPE and it stores all the fields' sizes and offsets.
Problem was to understand that BIT_FIELD_REF doesn't reference the bits itself: it is used like BIT_FIELD_REF & INTEGER_CST, where constant acts like mask. After understanding this, I quickly computed the offsets and got the name from the type.

Resources