Is it possible to see which lines were executed after a command-line app was run? - c++

I am using MinGW (GCC) as a C++ compiler within my application. I have set it to redirect the output of its command line process to my app. Now, suppose I have the following simple C++ code:
int n = 5;
if (n == 6) cout << "YES";
else cout << "NO";
Is there a way to tell what line(s) of code were actually hit during execution of the application? Is there a command I can send to MinGW (GCC) process which, for the given example, would output 1 and 3, as those were the lines hit. And also, in case of a line inside a "for" loop, to tell how many times that statement was actually hit?
And, if not possible, what would be the best approach to having this information? Developing my own compiler or...? Thanks in advance
EDIT: Can someone provide a snippet of commands (in Windows) to be used in order to create a coverage-enabled GCC exe file?

"Is there a way to tell what line(s) of code were actually hit during execution of the application?"
Yes. It's an intrinsic GCC feature. You'll need to compile and link your code with the --coverage, -lgcov or -fprofile-arcs options set.
The gcov tool can be used to consolidate and interpret the actual informations gathered during program runs, that were instrumented with --coverage.
A very good tool to produce browsable consolidated and fairly visualized covearage information from gcov outputs is lcov.

Since you're using mingw you should be able to use gcov: https://gcc.gnu.org/onlinedocs/gcc/Gcov.html

Related

gcc gprof/gcov/other - how to get sequence of function calls/exits + control flow statements

BACKGROUND
We have testers for our embedded GUI product and when a tester declares "test failed", sometimes it's hard for us developers to reproduce the exact problem because we don't have the exact trace of what happened.
We do currently have a logging framework but us devs have to manually input those logging statements in the code which is fine . . . except when a hard-to-reproduce bug occurs and we didn't have a log statement at the 'right' location and then when we re-build, re-run the test with the same steps, we get a different result.
ISSUE
We would like a solution wherein the compiler produces extra instrumentation code that allows us to see the exact sequence of events including, at the minimum:
function enter/exit (already provided by -finstrument-functions)
control-flow statement enter i.e. entering if/else, which case statement we jumped to
The log would look like this:
int main() entered
if-line 5 entered
else-line 10 entered
void EventLoop() entered
. . .
Some additional nice-to-haves are
Parameter values on function entry AND exit (for pass-by-reference types)
Function return value
QUESTION
Are there any gcc tools or even paid tools that can do this instrumentation automatically?
You can either use gdb for that, and you can automate that (I've got a tool for that in the works, you find it here or you can try to use gcov.
The gcov implementation is so, that it loads the latest gcov data when you start the program. But: you can manually dump and load the data. If you call __gcov_flush it will dump the current data and reset the current state. However: if you do that several times it will always merge the data, so you'd also need to rename the gcov data file then.

How to properly debug a binary generated by `go test -c` using GDB?

The go test command has support for the -c flag, described as follows:
-c Compile the test binary to pkg.test but do not run it.
(Where pkg is the last element of the package's import path.)
As far as I understand, generating a binary like this is the way to run it interactively using GDB. However, since the test binary is created by combining the source and test files temporarily in some /tmp/ directory, this is what happens when I run list in gdb:
Loading Go Runtime support.
(gdb) list
42 github.com/<username>/<project>/_test/_testmain.go: No such file or directory.
This means I cannot happily inspect the Go source code in GDB like I'm used to. I know it is possible to force the temporary directory to stay by passing the -work flag to the go test command, but then it is still a huge hassle since the binary is not created in that directory and such. I was wondering if anyone found a clean solution to this problem.
Go 1.5 has been released, and there is still no officially sanctioned Go debugger. I haven't had much success using GDB for effectively debugging Go programs or test binaries. However, I have had success using Delve, a non-official debugger that is still undergoing development: https://github.com/derekparker/delve
To run your test code in the debugger, simply install delve:
go get -u github.com/derekparker/delve/cmd/dlv
... and then start the tests in the debugger from within your workspace:
dlv test
From the debugger prompt, you can single-step, set breakpoints, etc.
Give it a whirl!
Unfortunately, this appears to be a known issue that's not going to be fixed. See this discussion:
https://groups.google.com/forum/#!topic/golang-nuts/nIA09gp3eNU
I've seen two solutions to this problem.
1) create a .gdbinit file with a set substitute-path command to
redirect gdb to the actual location of the source. This file could be
generated by the go tool but you'd risk overwriting someone's custom
.gdbinit file and would tie the go tool to gdb which seems like a bad
idea.
2) Replace the source file paths in the executable (which are pointing
to /tmp/...) with the location they reside on disk. This is
straightforward if the real path is shorter then the /tmp/... path.
This would likely require additional support from the compiler /
linker to make this solution more generic.
It spawned this issue on the Go Google Code issue tracker, to which the decision ended up being:
https://code.google.com/p/go/issues/detail?id=2881
This is annoying, but it is the least of many annoying possibilities.
As a rule, the go tool should not be scribbling in the source
directories, which might not even be writable, and it shouldn't be
leaving files elsewhere after it exits. There is next to nothing
interesting in _testmain.go. People testing with gdb can break on
testing.Main instead.
Russ
Status: Unfortunate
So, in short, it sucks, and while you can work around it and GDB a test executable, the development team is unlikely to make it as easy as it could be for you.
I'm still new to the golang game but for what it's worth basic debugging seems to work.
The list command you're trying to work can be used so long as you're already at a breakpoint somewhere in your code. For example:
(gdb) b aws.go:54
Breakpoint 1 at 0x61841: file /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go, line 54.
(gdb) r
Starting program: /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.test
[snip: some arnings about BinaryCache]
Breakpoint 1, github.com/stellar/deliverator/aws.imageIsNewer (latest=0xc2081fe2d0, ami=0xc2081fe3c0, ~r2=false)
at /Users/mat/gocode/src/github.com/stellar/deliverator/aws/aws.go:54
54 layout := "2006-01-02T15:04:05.000Z"
(gdb) list
49 func imageIsNewer(latest *ec2.Image, ami *ec2.Image) bool {
50 if latest == nil {
51 return true
52 }
53
54 layout := "2006-01-02T15:04:05.000Z"
55
56 amiCreationTime, amiErr := time.Parse(layout, *ami.CreationDate)
57 if amiErr != nil {
58 panic(amiErr)
This is just after running the following in the aws subdir of my project:
go test -c
gdb aws.test
As an additional caveat, it does seem very selective about where breakpoints can be placed. Seems like it has to be an expression but that conclusion is only via experimentation.
If you're willing to use tools besides GDB, check out godebug. To use it, first install with:
go get github.com/mailgun/godebug
Next, insert a breakpoint somewhere by adding the following statement to your code:
_ = "breakpoint"
Now run your tests with the godebug test command.
godebug test
It supports many of the parameters from the go test command.
-test.bench string
regular expression per path component to select benchmarks to run
-test.benchmem
print memory allocations for benchmarks
-test.benchtime duration
approximate run time for each benchmark (default 1s)
-test.blockprofile string
write a goroutine blocking profile to the named file after execution
-test.blockprofilerate int
if >= 0, calls runtime.SetBlockProfileRate() (default 1)
-test.count n
run tests and benchmarks n times (default 1)
-test.coverprofile string
write a coverage profile to the named file after execution
-test.cpu string
comma-separated list of number of CPUs to use for each test
-test.cpuprofile string
write a cpu profile to the named file during execution
-test.memprofile string
write a memory profile to the named file after execution
-test.memprofilerate int
if >=0, sets runtime.MemProfileRate
-test.outputdir string
directory in which to write profiles
-test.parallel int
maximum test parallelism (default 4)
-test.run string
regular expression to select tests and examples to run
-test.short
run smaller test suite to save time
-test.timeout duration
if positive, sets an aggregate time limit for all tests
-test.trace string
write an execution trace to the named file after execution
-test.v
verbose: print additional output

Clearing the screen in C++ using other compilers

Hello I'm interested in learning a way to clear the screen. I'm using C++ but it seem that some possible code to use are only known to work with Windows compilers. I'm using Ubuntu with a "g++ compiler".
code i have research in order to use and have tried...
---This don't work with g++ compiler
system("cls"); error: sh: 1: cls: not found
system("clrscr"); sh: 1: clrscr: not found
I stumble upon this code that it works, i know it prints lot's of lines ...
cout << string(50, '\n');
any cleaner methods that I could possibly use ?
The Unix command for clearing the terminal is clear.
Alternatively, send the terminal codes for doing same (this varies by terminal, but this sequence works for most):
cout << "\033[H\033[2J";
(I got the sequence by simply running clear | less on my system. Try it and see if you get the same result.)

QProcess Multiplatform command

I need to launch some script using QProcess.
For this, under windows, I use QProcess::execute("cmd [...]");.
However, this won't work if I go under some other OS such as Linux.
So, I was wondering if the best solution to make that code portable, would be to interfere with a mutliplatform scripting solution, such as TCL for exemple.
So I use : QProcess:execute("tclsh text.tcl"); and it works.
But, I got three questions concerning that problem. Because I'm not sure of what I've done.
Will execute() execute tclsh with the file test.tcl both under Windows and Linux wherever I execute it ? It seems to do so, but I want to be sure ! Is there any bad scenario that can happen ?
Is this a good solution ? I know lots of people have way more experience than I do, and I'd be grateful for anything I could learn !
Why not using std::system() ? Is it less portable ?
While this isn't a total answer, I can point out a few things.
In particular, tclsh is quite happy under Windows; it's a major supported platform. The main problem that could happen in practice is if you pass a filename with a space in it (this is distinctly more likely under Windows than on a Unix due to differences in community practice). However, the execute() as you have written it has no problems. Well, as long as tclsh is located on the PATH.
The other main option for integrating Tcl script execution with Qt is to link your program against the Tcl binary library and use that. Tcl's API is aimed at C, so it should be pretty simple to use from C++ (if a little clunky from a C++ perspective):
// This holds the description of the API
#include "tcl.h"
// Initialize the Tcl library; *call only once*
Tcl_FindExecutable(NULL);
// Make an evaluation context
Tcl_Interp *interp = Tcl_CreateInterp();
// Execute a script loaded from a file (or whatever)
int resultCode = Tcl_Eval(interp, "source test.tcl");
// Check if an error happened and print the error if it did
if (resultCode == TCL_ERROR) {
std::cerr << "ERROR: " << Tcl_GetString(Tcl_GetObjResult(interp)) << std::endl;
}
// Squelch the evaluation context
Tcl_DeleteInterp(interp);
I'm not a particularly great C++ coder, but this should give the idea. I have no idea about QProcess::execute() vs std::system().
A weak point of your solution is that on windows you'll have to install tclsh. There is no tclsh on Solaris either. May be somewhere else.
Compared to std::system(), QProcess gives you more control and information about the process of executing your command. If all you need is just to execute script (without receiving the output, for example) - std::system() is a good choice.
What I've used in a similar situation:
#ifdef Q_OS_WIN
mCommand = QString("cmd /C %1 %2").arg(command).arg(args);
#else
mCommand = QString("bash %1 %2").arg(command).arg(args);
#endif

Running c++ in browser

I have written some basic c++ programs in one of my classes for school. I was wondering if it was possible to somehow virtually run the program in a broswer. I would like to post the program to my website. Once its posted, a person could access the program, run the program, and, interact with the program. I'm not trying to write C++ for my website, it would be more for an interactive portfolio.
Is this possible?
Use codepad, a website which lets you compile and share code online.
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Hello, Stack Overflow!" << std::endl;
return 0;
}
There is also Google Native Client SDK that allows C++ code to run in browser. Microsoft Active X is also a viable option. I am only saying it is possible not recommended.
You can only run the program on your server, not on the client's machine.
At least not without downloading and manually executing it. Anything else would be an open door for malware...
I see two options, but both very overkill:
Write (or find) a C++ interpreter in JavaScript
Use a VM running an operating system (e.g. jslinux and demonstrate your programs there.
The sensible option is to just give people a way to view and download the source code, I guess.
Google chrome supports this: http://www.readwriteweb.com/cloud/2011/08/google-officially-announces-cc.php
But it's by no means "mainstream" or standards-based.
Another solution (codepad like) would be to use https://ideone.com/ which seems much nicer to use than codepad, more user-friendly, but does the same:
Allow you to write C++ (60 languages possibles) directly from the browser and compile it and render result in the browser (I tried using printf and it worked fine). Possibility of forking source code.
https://ideone.com/baYzfe
The following two programs are quite useful :
1) Ideone
2) Codepad
You can compile, run, and share code online in any browser.
You can use Emscripten to compile C++ to Javascript. Emscripten can compile LLVM bitcode to Javascript. Some demos of Emscripten can be found here, including a raytracer and a text-to-speech engine that was compiled from C++ to Javascript.
To run x86 binaries in a web browser, you could also use an emulator such as v86. This is one possible way to compile and run C++ programs in a browser.
One of the best sites for running C++ and other multiple languages online is Repl.it
This example: repl.it/#abranhe/stackoverflow
#include <iostream>
int main() {
std::cout << "Hello Stackoverflow\n";
return 0;
}
One of the biggest pros it has is that you can work with multiple files, working with header (header.h) files etc. None of the below websites provide this option:
Codepad.org
JSLinux
IDEone
I really recommend it! You will love it!
Also wanted to add Google Colab here as an option:
Cell 1:
%%writefile hello.cpp
#include <iostream>
int main(int argc, char** argv) {
std::cout << "Hello, Stack Overflow!" << std::endl;
return 0;
}
Cell 2:
%%script bash
g++ hello.cpp -o test
ls -laX
./test