c++ vscode debgging : can't access element of armadillo matrix - c++

I am trying to debug a c++ program from the vs code debug console, and I'd like to access some elements of an armadillo matrix, however when i try to acces the matrix I get the following:
-> matrx.at(0,2)
Cannot evaluate function -- may be inlined
-> matrx(0,2)
Expression of type other than "Function returning ..." used as function
The two ways of acessing wont evaluate, and I'm not sure what's missing. I can access it in the program but not in the debug console, and I have disabled optimization with -O0.

Related

How to start a REPL while debugging C++?

How can I get a REPL to evaluate simple things and test things out in the middle of a program's execution in C++?
I have some debugging tools at my disposal, lldb, but as far as I can tell, I can only view things, not test new things on the fly, even though it seems like it should be able to do it but maybe that functionality of the lldb debugger only works for Swift.
It doesn't have to be a complete REPL, but the ability to do some basic things would be so incredibly helpful. I am working with a massive binary in a new codebase with all sorts of types, classes, composition, and inheritance going on that's overwhelming and undocumented, and every test and repeat of the 50GB binary is about 10 minutes which is painful (running unit tests takes the same 10 minutes). It would be great if I could test statements out in a REPL on a breakpoint in the middle of the execution, one statement after another to play around and figure things out faster.
I'm coming from a drop into ipython/ipdb background, as well as the same lldb for Swift. Very new to C++.
The lldb command expr - aliased to p - should do what you want. expr will run the code you provide "as though it had been inserted in the current context" and will return the expression's result. So for instance, if you have a function and want to see what it returns for various inputs, you can do:
(lldb) expr my_new_function(10, 20, 30)
You can even debug functions while handling such interesting inputs by doing:
(lldb) break set -n my_new_function
(lldb) expr -i 0 -- my_new_function(10, 20, 30)
the -i tells lldb to stop on the breakpoint, by default lldb ignores breakpoints in hand called functions.
You can also define new objects & structs in the expression command, but unlike the Swift REPL mode(*) user-defined objects, functions & variables have to be named with an initial $ to keep them from getting confused with names from your code. For instance, if you have a class A:
(lldb) expr A $myA()
will make a default-constructed object of type A, then you can call methods on it:
(lldb) expr $myA().doSomething()
Note that C++ templates are poorly described in debug information - the current standard only describes instantiations and not the abstract template form. So YMMV when trying to create objects of complex template types. The other danger with C++ is that some functions you want to call may only exist as inlined code, which the debugger can't invoke. This happens for some of the STL types, e.g. the size() method is often not callable on vectors & the like because it's always inlined. That's less of a problem with -O0 code, however.
(*) When you run swift in Terminal w/o arguments to bring up the Swift REPL, you are actually just running lldb in a fancy input mode that feeds what you type to the expr command under the covers. The main difference between the bare expr and the full Swift REPL is that the REPL is focused on making new code, whereas expr is more meant for exploring the code you are stopped in right now, so the name lookup rules are different. There isn't a full C++ REPL mostly because we don't know how to do jobs like "build C++ classes incrementally", which would be required for a real REPL.

Can't see function output while using gdb, (Error accessing memory address.. Input/output error)

I'm seeing a problem in using gdb (actually I'm using ddd which is a grahpic debugger using gdb inside) which is that I cannot see a function's return value.
With a simple program, I could see that I can print a function's output. For example, if an object.peek() return an integer, if I type p object.peek(), then I get for example 1234. And I remember printing any values when I'm degging a C or C++ program.
I'm now running and analyzing a complex program which is a python program containing a shared object library written in C++. I can set a breakpoint in C++ code and follow steps. But when I try to see some functions' output like param.input_dim_size(), the debugger give me the output :
(gdb) p param.input_dim_size()
Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0x232460: Input/output error.
An error occurred while in a function called from GDB.
Evaluation of the expression containing the function
(caffe::NetParameter::input_dim_size() const) will be abandoned.
When the function is done executing, GDB will silently stop.
Has is something to do with attaching two debuggers to the same program? or using C++ library inside Python? (I guess not). Or is there any restriction for seeing the output of functions in gdb?

Fortran script only runs when print statement added

I am running an atmospheric model, and need to compile an executable to convert some files. If I compile the code as supplied, it runs but it gets stuck and doesn't ever complete. It doesn't give an error or anything like that.
After doing some testing by adding print statements to see where it was getting stuck, I've found that the executable only runs if I compile the code with a print statement in one of the subroutines.
The piece of code in question is the one here. Specifically, the code fails to run unless I put a print statement somewhere in the get_bottom_top_dim subroutine.
Does anyone know why this might be? It doesn't matter what the print statement is (currently I'm using print*, '!'). but as soon as I remove it or comment it out, the code no longer works.
I'm assuming it must have something to do with my machine or compiler (ifort 12.1.0), but I'm stumped as to what the problem is!
This is an extended comment rather than an answer:
The situation you describe, inserting a print statement which apparently fixes a program, often arises when the underlying problem is due to either
a) an attempt to access an element outside the declared bounds of an array; or
b) a mismatch between dummy and actual arguments to some procedure.
Recompile your program with the compiler options to check interfaces at compile-time and to check array bounds at run-time.
Fortran has evolved a LOT since I last used it but here's how to go about solving your problem.
Think of some hypotheses that could explain the symptoms, e.g. the compiler is optimizing the subroutine down to a no-op when it has no print side effect. Or a compiler bug is translating this code into something empty or an infinite loop or crashing code. (What exactly do you mean by "fails to run"?) Or the Linker is failing to link in some needed code unless the subroutine explicitly calls print.
Or there's a bug in this subroutine and the print statement alters its symptoms e.g. by changing which data gets overwritten by an index-out-of-bounds bug.
Think of ways to test these hypotheses. You might already have observations adequate to rule out of some of them. You could decompile the object code to see if this subroutine is empty. Or step through it in a debugger. Or replace the print statement with a different side effect like logging to a file or to an in-memory text buffer.
Or turn on all optional runtime memory checks and compile time warnings. Or simplify the code until the problem goes away, then binary search on bringing back code until the problem recurs.
Do the most likely or easiest tests first. Rule out some hypotheses, and iterate.
I had a similar bug and I found that the problem was in the dependencies on the makefile.
This was what I had:
I set a variable with a value and the program stops.
I write a print command and it works.
I delete the print statement and continues to work.
I alter the variable value and stops.
The thing is, the variable value is set in a parameters.f90
The print statement is in a file H3.f90 that depends on parameters.f90 but it was not declared on the makefile.
After correcting:
h3.o: h3.f90 variables.f90 parameters.f90
$(FC) -c h3.f90
It all worked properly.

Visual Studio Debugger Watch problems

How can I find out the address of a variable on the stack in the visual studio debugger watch window (or elsewhere?)
Reading the variable works fine:
streets streets [11790](0x1c66a690 [...] std::vector<Street *,std::allocator<Street *> >
But prefixing with & doesn't give me an address:
&streets streets [11790](0x1c66a690 [...] std::vector<Street *,std::allocator<Street *> >
Also, trying to read the size doesn't work, why is that?
streets.size() CXX0075: Error: Cannot set up Function Evaluation
The program is compiled in debug mode.
The Visual Studio Debugger drives debugger watch, quick-watch, auto, and local variable views through a translation defined by schema in a file called autoexp.dat (depending on your VS version, the content therein can vary markedly). The file is located in your VS-InstallDir/Common7/Packages/Debugger folder (at least it is for VS2010 and VS2012).
Knowing this, a couple of ideas for you to try/consider:
Method One: Library Know-How
To access the actual address of the first element within the vector I ultimately just do this:
streets._Myfirst
if you know the number of elements you're going to view, you can use the array-expansion extension by:
streets._Myfirst,N
where N is the number of elements
Note: this only works as shown above with vectors. The practice is different depending on which container you are using. There are no-doubt simpler ways that are probably less dependent on the implementation of std::vector<>, but this is the simplest wasy I know how to get you up and debugging quickly.
Method Two: Scorched Earth
Under Tools/Options/Debugging/General is a list of features you can switch on and off. One of them you will find particularly useful to this question:
Show raw structure of objects in variable windows.
Turn this ON to see raw member variables of all structures and containers, including standard containers like std::vector<>. This effectively disables usage of the templates in autoexp.dat
To see the address, cast to a void *, like so: (void *)&streets.
This is Visual Studio's attempt to be helpful by showing you the pointed-to vector directly. A similar problem affects arrays of vectors.

Why is passing a char* to this method failing?

I have a C++ method such as:
bool MyClass::Foo(char* charPointer)
{
return CallExternalAPIFunction(charPointer);
}
Now I have some static method somewhere else such as:
bool MyOtherClass::DoFoo(char* charPointer)
{
return _myClassObject.Foo(charPointer);
}
My issue is that my code breaks at that point. It doesn't exit the application or anything, it just never returns any value. To try and pinpoint the issue, I stepped through the code using the Visual Studio 2010 debugger and noticed something weird.
When I step into the DoFoo function and hover over charPointer, I actually see the value it was called with (an IP address string in this case). However, when I step into Foo and hover over charPointer, nothing shows up and the external API function call never returns (it's like it's just stepped over) and my program resumes it's execution after the call to DoFoo.
I also tried using the Exception... feature of the VS debugger (to pick up first chance exceptions) but it never picked up anything.
Has this ever happened to anyone? Am I doing something wrong?
Thank you.
You need to build the project with Debug settings. Release settings mean that optimizations are enabled and optimizations make debugging a beating.
Without optimizations, there is a very close correspondence between statements in your C++ code and blocks of machine code in the program. The program is slower (often far slower) but it's easier to debug because you can observe what each statement does.
The optimizer reorders your code, eliminates variables, inlines functions, unrolls loops, and does all sorts of other things to make the program fast. The program is faster (often much faster) but it's far more difficult to debug because the correspondence between the statements in your C++ code and the instructions in the machine code is no longer there.