DIA SDK how to get parent function of FuncDebugStart / FuncDebugEnd? - windows

The documentation for SymTagFuncDebugStart and SymTagFuncDebugEnd state that calling IDiaSymbol::get_lexicalParent will return a symbol for the enclosing function. I interpret this as I will get an IDiaSymbol whose get_symTag method returns SymTagFunction. However, when I do this it returns me the SymTagCompiland and not the function. So the documentation appears wrong, but worse I'm not sure how to actually tie the SymTagFuncDebugStart and SymTagFuncDebugEnd to the containing SymTagFunction.
Does anyone know? A few dumps suggest that SymTagFuncDebugStart and SymTagFuncDebugEnd always come immediately after the corresponding SymTagFunction when enumerating the symbols via IEnumSymbols. Or put another way, that if IDiaSymbol::get_symIndexId returns n for the function, it will return n+1 and n+2 respectively for the func debug start and func debug end.
But I can't be sure this is always true, and this seems unreliable and hackish.
Does anyone have any suggestions on the correct way to do this?

Could you paste your code here? I guess there is something wrong in your code. Call get_lexicalParent on SymTagFuncDebugStart and SymTagFuncDebugEnd should return the symbol associated the enclosing function (SymTagFunction).

I got this working eventually. The problem is that when you enumerate all the symbols in the global scope using SymTagNull, you will find the FuncDebugStart and FuncDebugEnd symbols. The lexical parent of these symbols is the global scope, because it's the "parent" in the sense that it vended you the pointers to the FuncDebugStart and FuncDebugEnd symbols.
If you get the FuncDebugStart and FuncDebugEnd by calling findChildren on an actual SymTagFunction symbol, however, then its lexical parent will in fact be the original function. So this was an issue of unclear documentation.

Related

Recursive variable declaration

I have just seen this black magic in folly/ManualExecutor.h
TimePoint now_ = now_.min();
After I grep'ed the whole library source code, I haven't seen a definition of the variable now_ anywhere else than here. What's happening here? Is this effectively some sort recursive variable declaration?
That code is most likely equal to this:
TimePoint now_ = TimePoint::min();
That means, min() is a static method, and calling it using an instance is same as calling it like this, the instance is used just for determining the type. No black magic involved, that's just two syntaxes for doing the same thing.
As to why the code in question compiles: now_ is already declared by the left side of the line, so when it's used for initialization on the right side, compiler already knows its type and is able to call the static method. Trying to call non-static method should give an error (see comment of #BenVoigt below).
As demonstrated by the fact that you had to write this question, the syntax in the question is not the most clear. It may be tempting if type name long, and is perhaps justifiable in member variable declarations with initializer (which the question code is). In code inside functions, auto is better way to reduce repetition.
Digging into the code shows that TimePoint is an alias for chrono::steady_clock::time_point, where min() is indeed a static method that returns the minimum allowable duration:
http://en.cppreference.com/w/cpp/chrono/time_point/min

Type mismatch when calling a function in qtp

I am using QTP 11.5 for automating a web application.I am trying to call an action in qtp through driverscript as below:
RFSTestPath = "D:\vf74\D Drive\RFS Automation\"
LoadAndRunAction RFStestPath & LogInApplication,"Action1",oneIteration
Inside the LogInApplication(Action1) am calling a login function as:
Call fncLogInApplication(strURL,strUsesrName,strPasssword)
Definition of fncLogInApplication is written in fncLogInApplication.vbs
When I associate the fncLogInApplication.vbs file to driverscript, am able to execute my code without any errors. But when I de-associate .vbs file from driverscript and associate it to LogInApplication test am getting "Type mismatch: 'fncLogInApplication'"
Can anyone help me in the association please. I want fncLogInApplication to be executed when I associate to LogInApplication not to the main driverscript.
Please comment back if you require any more info
There is only one set of associated libraries that is active at any one time: That is always the outermost test's one.
This means if test A calls test B, test B will be executed with the libraries loaded based upon test A´s associated libraries list, not B's.
This also means that if B depends on a library, and B associated this library, but is called from test A (which does not associated this library), then B will fail to call (locate) the function since the associated libraries of B are never loaded (only those from A are). (As would A, naturally.).
If you are still interested: "Type mismatch" is QTPs (or VBScript´s) poor way of telling you: "The function called is not known, so I bet you instead meant an array variable dereference, and the variable you specified is equal to empty, so it is not an array, and thus cannot be dereferenced as an array variable, which is what I call a 'type mismatch'."
This reasoning is valid, considering the syntax tree of VB/VBScript: Function calls and array variable dereferences cannot be formally differentiated. Syntactically, they are very similar, or identical in most cases. So be prepared to handle "Type mismatch" like the "Unknown function referenced" message that VB/VBScript never display when creating VBScript code.
You can, however, load the library you want in test B´s code (for example, using LoadFunctionLibrary), but this still allows A to call functions from that library once B loaded it and returned from A´s call. This, and all the possible variations of this procedure, however, have side-effects to aspects like debugging, forward references and visibility of global variables, so I would recommend against it.
Additional notes:
There is no good reason to use CALL. Just call the sub or function.
If you call a function and use the result it returns, you must include the arguments in parantheses.
If you call a sub (or a function, and don´t use the result it returns), you must not include the arguments in parantheses. If the sub or function accepts only one argument, it might look like you are allowed to put it in parantheses, but this is not true. In this case, the argument is simply treated like a term in parantheses.
The argument "bracketing" aspects just listed can create very nasty bugs, especially if the argument is byRef, also due (but not limited) to the fact that VBScripts unfortunately allows you to pass values for a byRef argument (where a variable parameter is expected), so it is generally a good idea to put paranthesis only where it belongs (i.e. where absolutely needed).

scala coalesces multiple function call parameters into a Tuple -- can this be disabled?

This is a troublesome violation of type safety in my project, so I'm looking for a way to disable it. It seems that if a function takes an AnyRef (or a java.lang.Object), you can call the function with any combination of parameters, and Scala will coalesce the parameters into a Tuple object and invoke the function.
In my case the function isn't expecting a Tuple, and fails at runtime. I would expect this situation to be caught at compile time.
object WhyTuple {
def main(args: Array[String]): Unit = {
fooIt("foo", "bar")
}
def fooIt(o: AnyRef) {
println(o.toString)
}
}
Output:
(foo,bar)
No implicits or Predef at play here at all -- just good old fashioned compiler magic. You can find it in the type checker. I can't locate it in the spec right now.
If you're motivated enough, you could add a -X option to the compiler prevent this.
Alternatively, you could avoid writing arity-1 methods that accept a supertype of TupleN.
What about something like this:
object Qx2 {
#deprecated def callingWithATupleProducesAWarning(a: Product) = 2
def callingWithATupleProducesAWarning(a: Any) = 3
}
Tuples have the Product trait, so any call to callingWithATupleProducesAWarning that passes a tuple will produce a deprecation warning.
Edit: According to people better informed than me, the following answer is actually wrong: see this answer. Thanks Aaron Novstrup for pointing this out.
This is actually a quirk of the parser, not of the type system or the compiler. Scala allows zero- or one-arg functions to be invoked without parentheses, but not functions with more than one argument. So as Fred Haslam says, what you've written isn't an invocation with two arguments, it's an invocation with one tuple-valued argument. However, if the method did take two arguments, the invocation would be a two-arg invocation. It seems like the meaning of the code affects how it parses (which is a bit suckful).
As for what you can actually do about this, that's tricky. If the method really did require two arguments, this problem would go away (i.e. if someone then mistakenly tried to call it with one argument or with three, they'd get a compile error as you expect). Don't suppose there's some extra parameter you've been putting off adding to that method? :)
The compile is capable of interpreting methods without round brackets. So it takes the round brackets in the fooIt to mean Tuple. Your call is the same as:
fooIt( ("foo","bar") )
That being said, you can cause the method to exclude the call, and retrieve the value if you use some wrapper like Some(AnyRef) or Tuple1(AnyRef).
I think the definition of (x, y) in Predef is responsible. The "-Yno-predefs" compiler flag might be of some use, assuming you're willing to do the work of manually importing any implicits you otherwise need. By that I mean that you'll have to add import scala.Predef._ all over the place.
Could you also add a two-param override, which would prevent the compiler applying the syntactic sugar? By making the types taking suitably obscure you're unlikely to get false positives. E.g:
object WhyTuple {
...
class DummyType
def fooIt(a: DummyType, b: DummyType) {
throw new UnsupportedOperationException("Dummy function - should not be called")
}
}

dumping the source code for an anonymous function

original (update follows)
I'm working with a lot of anonymous functions, ie functions declared as part of a dictionary, aka "methods". It's getting pretty painful to debug, because I can't tell what function the errors are happening in.
Vim's backtraces look like this:
Error detected while processing function NamedFunction..2111..2105:
line 1:
E730: using List as a String
This trace shows that the error occurred in the third level down the stack, on the first line of anonymous function #2105. IE NamedFunction called anonymous function #2111, which called anonymous function #2105. NamedFunction is one declared through the normal function NamedFunction() ... endfunction syntax; the others were declared using code like function dict.func() ... endfunction.
So obviously I'd like to find out which function has number 2105.
Assuming that it's still in scope, it's possible to find out what Dictionary entry references it by dumping all of the dictionary variables that might contain that reference. This is sort of awkward and it's difficult to be systematic about it, though I guess I could code up a function to search through all of the loaded dictionaries for a reference to that function, watching out for circular references. Although to be really thorough, it would have to search not only script-local and global dictionaries, but buffer-local dictionaries as well; is there a way to access another buffer's local variables?
Anyway I'm wondering if it's possible to dump the source code for the anonymous function instead. This would be a lot easier and probably more reliable.
update
I ended up asking about this a while back on the vim_use mailing list. Bram Moolenar, aka vim's BDFL, responded by saying that "You are not supposed to use the function number." However, a suitable alternative for this functionality has not been suggested, as of early September 2010. It's also not been explicitly mentioned whether or not this functionality will continue to work in subsequent vim releases. I've not tried to do this (or anything else, for that matter) in the recently released vim 7.3.
The :function command tries to stop you from specifying the numbered functions (their name is just a number) but you can trick it using the {...} dynamic function name feature, throw in some :verbose and you have a winner:
:verbose function {43}
function 43()
Last set from /home/peter/test.vim
1 throw "I am an exception"
endfunction
This was not at all obvious in the help docs.
I use the following workaround: I have one plugin that does some stuff like creating commands, global functions for other plugins. It also registers all plugins, so I have a large dictionary with lots of stuff related to plugins. If I see a error I search for a function that produces it using function findnr:
"{{{3 stuf.findf:
function s:F.stuf.findf(nr, pos, d)
if type(a:d)==2 && string(a:d)=~#"'".a:nr."'"
return a:pos
elseif type(a:d)==type({})
for [key, Value] in items(a:d)
let pos=s:F.stuf.findf(a:nr, a:pos."/".key, Value)
unlet Value
if type(pos)==type("")
return pos
endif
endfor
endif
return 0
endfunction
"{{{3 stuf.findr:
function s:F.stuf.findnr(nr)
for [key, value] in items(s:g.reg.registered)+[["load", {"F": s:F}]]
let pos=s:F.stuf.findf(a:nr, "/".key, value.F)
if type(pos)==type("")
return pos
endif
endfor
return 0
endfunction
Here I have this plugin functions in s:F.{key} dictionaries and other plugins' functions under s:g.reg.registered[plugname].F dictionary.

Garbage collection with Ruby C Extension

I am working my way through Ferret (Ruby port of Lucene) code to solve
a bug. Ferret code is mainly a C extension to Ruby. I am running into
some issues with the garbage collector. I managed to fix it, but I
don't completely understand my fix =) I am hoping someone with deeper
knowledge of Ruby and C extension (this is my 3rd day with Ruby) can
elaborate. Thanks.
Here is the situation:
Some where in Ferret C code, I am returning a "Token" to Ruby land.
The code looks like
static VALUE get_token (...)
{
...
RToken *token = ALLOC(RToken);
token->text = rb_str_new2("some text");
return Data_Wrap_Struct(..., &frt_token_mark, &frt_token_free, token);
}
frt_token_mark calls rb_gc_mark(token->text) and frt_token_free
just frees the token with free(token)
In Ruby, this code correlates to the following:
token = #input.next
Basically, #input is set to some object, calling the next method on it
triggers the get_token C call, which returns a token object.
In Ruby land, I then do something like w = token.text.scan('\w+')
When I run this code inside a while 1 loop (to isolate my problem), at
some point (roughly when my ruby process mem footprint goes to 256MB,
probably some GC threshold), Ruby dies with errors like
scan method called on terminated object
Or just core dumps. My guess was that token.text was garbage collected.
I don't know enough about Ruby C extension to know what happens with
Data_Wrap_Struct returned objects. Seems to me the assignment in Ruby
land, token =, should create a reference to it.
My "work-around"/"fix" is to create a Ruby instance variable in the
object referred to by #input, and stores the token text in there, to
get an extra reference to it. So the C code looks like
RToken *token = ALLOC(RToken);
token->text = rb_str_new2(tk->text);
/* added code: prevent garbage collection */
rb_ivar_set(input, id_curtoken, token->text);
return Data_Wrap_Struct(cToken, &frt_token_mark, &frt_token_free, token);
So now I've created a "curtoken" in the input instance variable, and
saved a copy of the text there... I've taken care to remove/delete
this reference in the free callback of the class for #input.
With this code, it works in that I no longer get the terminated object
error.
The fix seems to make sense to me -- it keeps an extra ref in curtoken
to the token.text string so an instance of token.text won't be removed
until the next time #input.next is called (at which time a different
token.text replaces the old value in curtoken).
My question is: why did it not work before? Shouldn't
Data_Wrap_Structure return an object that, when assigned in Ruby land,
has a valid reference and not be removed by Ruby?
Thanks.
When the Ruby garbage collector is invoked, it has a mark phase and a sweep phase. The mark phase marks all objects in the system by marking:
all objects referenced by a ruby stack frame (e.g. local variables)
all globally accessible objects (e.g. referred to by a constant or global variable) and their children/referents, and
all objects referred to by a reference on the stack, as well as those objects' children/referents.
as well as a number of other objects that are not important to this discussion. The sweep phase then destroys any objects that are not accessible (i.e. those that were not marked).
Data_Wrap_Struct returns a reference to an object. As long as that reference is available to ruby code (e.g. stored in a local variable) or is on the stack (referred to by a local C variable), the object should not be swept.
It's looks like from what you've posted that token->text is getting garbage collected. But why is it getting collected? It must not be getting marked. Is the Token object itself getting marked? If it is, then token->text should be getting marked. Try setting a breakpoint or printing a message in the token's mark function to see.
If the token is not getting marked, then the next step is to figure out why. If it is getting marked, then the next step is to figure out why the string returned by the text() method is getting swept (maybe it's not the same object that is getting marked).
Also, are you sure that it is the token's text member that is causing the exception? Looking at:
http://github.com/dbalmain/ferret/blob/master/ruby/ext/r_analysis.c
I see that the token and the token stream both have text() methods. The TokenStream struct doesn't hold a reference to its text object (it can't, as it's a C struct with no knowledge of ruby). Thus, the Ruby object wrapping the C struct needs to hold the reference (and this is being done with rb_ivar_set).
The RToken struct shouldn't need to do this, because it marks its text member in its mark function.
One more thing: you may be able to reproduce this bug by calling GC.start explicitly in your loop rather than having to allocate so many objects that the garbage collector kicks in. This won't fix the problem but might make diagnosis simpler.
perhaps mark as volatile:
http://www.justskins.com/forums/chasing-a-garbage-collection-bug-98766.html
maybe your compile is keeping its reference in a registry instead of the stack...there is some way mentioned I think in README.EXT to force an object to never be GC'ed, but...the question still remains as to why it's being collected early...

Resources