We have a Tcl built in our C/C++ application, I found the place in our code where Tcl_EvalObjv is called if the command was not found. I have to admit that the code is pretty old and not many of our developers know what happens in this module.
It looks like this:
// ... there is some checking if command is registered etc., it fails and the code goes here:
std::vector<Tcl_Obj*> tclArgs = { NULL };
for (int i = 1; i < objc; ++i)
tclArgs.push_back(objv[i]);
tclArgs.shrink_to_fit();
// ...
tclArgs[0] = ::Tcl_NewStringObj(ORIGINAL_UNKNOWN, ORIGINAL_UNKNOWN_SIZE);
Tcl_IncrRefCount(tclArgs[0]);
::Tcl_ExposeCommand(pInterp, ORIGINAL_UNKNOWN, ORIGINAL_UNKNOWN);
result = ::Tcl_EvalObjv(pInterp, objc, &tclArgs[0], TCL_EVAL_GLOBAL); //<--
::Tcl_HideCommand(pInterp, ORIGINAL_UNKNOWN, ORIGINAL_UNKNOWN);
// ORIGINAL_UNKNOWN is char* it is just "unknown"
We have handlers for commands in our application, while executing Tcl_EvalObjv in CmdUnknown() function Tcl sometimes calls different commands. Examples below:
List of existing commands: "banana", "applepie", "carpet", "card"
Command: "apple", Tcl calls "applepie" (wrong, "apple" is not "applepie")
Command: "blah", Tcl gives error (correctly).
Command: "car", Tcl gives error (correctly, maybe because of 2 similar commands).
Is there are some kind of mechanism that Tcl does when it fails in searching for command? The thing is that I can't find anything that is related to our code that would complete the commands so maybe Tcl does?
As glenn hinted at, Tcl in interactive (REPL) mode allows for dispatching commands using some minimal but unambiguous name prefix. I cannot tell how your embedded Tcl is configured, initialised, and ended up being run as in interactive mode. However, you may want to try to "turn off" (toggle) the interactive mode, by either:
unset ::tcl_interactive
or
set ::tcl_interactive 0
All of this is implemented by the default unknown handler. Watch out for how the list of cmds is looked up and how it is treated differently when tcl_interactive is true or false:
puts [info body unknown]
Related
Hi I need to write a lldb breakpoint command that evaluates a value and prints out a value.
In gdb I could do it like this:
if ($value==2)
printf "Value is 2\n"
end
But in lldb the 'if-statement' is invalid it seems:
failed with error: 'if' is not a valid command.
error: Unrecognized command 'if'.
Can anyone tell me how to write this comparison inside my breakpoint command? Thanks!
You can use the expression parser to achieve this effect in some cases, and you can use the lldb Python interpreter for whatever complex work you want to do in response to a breakpoint hit. Given the fairly deep level of Python support, we felt if you don't know Python, you time would be better spent learning a little bit of that so you could really script lldb, rather than learning whatever little micro-language we would come up with.
Anyway, so using the interpreter, you could for instance do:
expr if ($value == 2) { (int) printf("Value is 2\n"); }
And using the python interpreter you can write a callback like:
def myCallback (frame, breakpoint_location, dict):
value = frame.FindValue("$value", lldb.eValueTypeConstResult)
if (value.unsigned == 10):
print "Value is 10"
put that in a file called myModule.py, do:
(lldb) command script import myModule.py
and then assign the command to your breakpoint with:
(lldb) breakpoint command add -F myModule.myCallback <BREAKPOINT_NUMBER>
That python example was a little more complex than normal because you were looking up lldb's equivalent of gdb's "convenience variable". If you were looking up a local, you could use frame.FindVariable.
More details on this at:
http://lldb.llvm.org/python-reference.html
Inside a scripted gdb session I want to use monitor <cmd> where cmd should contain the address of a symbol. For example:
monitor foobar &myVariable
should become to:
monitor foobar 0x00004711
Because the remote side cannot evaluate the expression. Whatever I tried, the string "&myVariable" gets sent instead of the address.
I played around with convenience variables and stuff, but this is the only workaround I found:
# write the command into a file and execute this file
# didn't find a direct way to include the address into the monitor command
set logging overwrite on
set logging on command.tmp
printf "monitor foobar 0x%08x\n", &myVariable
set logging off
source command.tmp
Any ideas to solve this in a more elegant way?
The simplest way to do this is to use the gdb eval command, which was introduced for exactly this purpose. It works a bit like printf:
(gdb) eval "monitor foobar %p", &myVariable
(I didn't actually try this, so caution.)
If your gdb doesn't have eval, then it is on the old side. I would suggest upgrading.
If you can't upgrade, then you can also script this using Python.
If your gdb doesn't have Python, then it is either very old (upgrade!) or compiled without Python support (recompile!).
If you can't manage to get either of these features, then I am afraid the "write out a script and source it" approach is all that is left.
I have a c++ program that run a command and pass some arguments to it. The code is as follow:
int RunApplication(fs::path applicationPathName,std::string arguments)
{
std::string applicationShortPath=GetShortFileName(applicationPathName);
std::string cmd="\""+applicationShortPath +"\" "+ arguments+" >>log.txt 2>&1 \"";
std::cout<<cmd<<std::endl;
int result=std::system(cmd.c_str());
return result;
}
When I run system command, the cmd window appears shortly and then closes, but the result is 1 and the cmd was not run (the command should generate output which is not generated).
To check that the cmd is correct, I stopped the application just before system line and copy/ paste cmd content to a cmd window and it worked.
I am wondering how can I find why application is not run in system()?
the cmd has this value just before running it:
"D:/DEVELO~3/x64/Debug/enfuse.exe" -w --hard-mask --exposure-weight=1 --saturation-weight=0.328 --contrast-weight=0.164 -o "C:/Users/m/AppData/Local/Temp/1.tif" "C:/Users/m/AppData/Local/Temp/1.jpg" "C:/Users/m/AppData/Local/Temp/2.jpg" >>log.txt 2>&1 "
How can I find why it is not working?
Is there any way that I set the system so it doesn't close cmd window so I can inspect it?
is there any better way to run a command on OS?
Does Boost has any solution for this?
Edit
After running it with cmd /k, I get this error message:
The input line is too long.
How can I fix it other than reducing cmd line?
There are two different things here: if you have to start a suprocess, "system" is not the best way of doing it (better to use the proper API, like CreateProcess, or a multiplatform wrapper, but avoid to go through the command interpreter, to avoid to open to potential malware injection).
But in this case system() is probably the right way to go since you in fact need the command interpreter (you cannot manage things like >>log.txt 2>&1 with only a process creation.)
The problem looks like a failure in the called program: may be the path is not correct or some of the files it has to work with are not existent or accessible with appropriate-permission and so on.
One of the firt thing to do: open a command prompt and paste the string you posted, in there. Does it run? Does it say something about any error?
Another thing to check is how escape sequence are used in C++ literals: to get a '\', you need '\\' since the first is the escape for the second (like \n, or \t etc.). Although it seems not the case, here, it is one of the most common mistakes.
Use cmd /k to keep the terminal: http://ss64.com/nt/cmd.html
Or just spawn cmd.exe instead and inspect the environment, permissions, etc. You can manually paste that command to see whether it would work from that shell. If it does, you know that paths, permssions and environment are ok, so you have some other issue on your hands (argument escaping, character encoding issues)
Check here How to execute a command and get output of command within C++ using POSIX?
Boost.Process is not official yet http://www.highscore.de/boost/process/
I've written a command line tool that I want to test (I'm not looking to run unit tests from command line). I want to map a specific set of input options to a specific output. I haven't been able to find any existing tools for this. The application is just a binary and could be written in any language but it accepts POSIX options and writes to standard output.
Something along the lines of:
For each known set of input options:
Launch application with specified input.
Pipe output to a file.
Diff output to stored (desired) output.
If diff is not empty, record error.
(Btw, is this what you call an integration test rather than a unit test?)
Edit: I know how I would go about writing my own tool for this, I don't need help with the code. What I want to learn is if this has already been done.
DejaGnu is a mature and somewhat standard framework for writing test suites for CLI programs.
Here is a sample test taken from this tutorial:
# send a string to the running program being tested:
send "echo Hello world!\n"
# inspect the output and determine whether the test passes or fails:
expect {
-re "Hello world.*$prompt $" {
pass "Echo test"
}
-re "$prompt $" {
fail "Echo test"
}
timeout {
fail "(timeout) Echo test"
}
}
Using a well-established framework like this is probably going to be better in the long run than anything you can come up with yourself, unless your needs are very simple.
You are looking for BATS (Bash Automated Testing System):
https://github.com/bats-core/bats-core
From the docs:
example.bats contains
#!/usr/bin/env bats
#test "addition using bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
#test "addition using dc" {
result="$(echo 2 2+p | dc)"
[ "$result" -eq 4 ]
}
$ bats example.bats
✓ addition using bc
✓ addition using dc
2 tests, 0 failures
bats-core
Well, I think every language should have a way of execute an external process.
In C#, you could do something like:
var p = new Process();
p.StartInfo = new ProcessStartInfo(#"C:\file-to-execute.exe");
... //You can set parameters here, etc.
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.UseShellExecute = false;
p.Start();
//To read the standard output:
var output = p.StandardOutput.ReadToEnd();
I have never had to write to the standard input, but I believe it can be done by accessing to p.StandardInput as well. The idea is to treat both inputs as Stream objects, because that's what they are.
In Python there is the subprocess module. According to its documentation:
The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.
I had to do the same when writing unit tests for the code generation part of a compiler I write some months ago: Writing unit tests in my compiler (which generates IL)
We wrote should, a single-file Python program to test any CLI tool. The default usage is to check that a line of the output contains some pattern. From the docs:
# A .should file launches any command it encounters.
echo "hello, world"
# Lines containing a `:` are test lines.
# The `test expression` is what is found at the right of the `:`.
# Here 'world' should be found on stdout, at least in one line.
:world
# What is at the left of the `:` are modifiers.
# One can specify the exact number of lines where the test expression has to appear.
# 'moon' should not be found on stdout.
0:moon
Should can check occurrences counts, look for regular expressions, use variables, filter tests, parse json data, and check exit codes.
Sure, it's been done literally thousands of times. But writing a tool to run simple shell scripts or batch files like what you propose is a trivial task, hardly worth trying to turn into a generic tool.
How can we list all the functions being called in an application. I tried using GDB but its backtrace list only upto the main function call.
I need deeper list i.e list of all the functions being called by the main function and the function being called from these called functions and so on.
Is there a way to get this in gdb? Or could you give me suggestions on how to get this?
How can we list all the functions being called in an application
For any realistically sized application, this list will have thousands of entries, which will probably make it useless.
You can find out all functions defined (but not necessarily called) in an application with the nm command, e.g.
nm /path/to/a.out | egrep ' [TW] '
You can also use GDB to set a breakpoint on each function:
(gdb) set logging on # collect trace in gdb.txt
(gdb) set confirm off # you wouldn't want to confirm every one of them
(gdb) rbreak . # set a breakpoint on each function
Once you continue, you'll hit a breakpoint for each function called. Use the disable and continue commands to move forward. I don't believe there is an easy way to automate that, unless you want to use Python scripting.
Already mentioned gprof is another good option.
You want a call graph. The tool that you want to use is not gdb, it's gprof. You compile your program with -pg and then run it. When it runs a file gmon.out will be produced. You then process this file with gprof and enjoy the output.
record function-call-history
https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html
This should be a great hardware accelerated possibility if you are one of the few people (2015) with a CPU that supports Intel Processor Tracing (Intel PT, intel_pt in /proc/cpuinfo).
GDB docs claim that it can produce output like:
(gdb) list 1, 10
1 void foo (void)
2 {
3 }
4
5 void bar (void)
6 {
7 ...
8 foo ();
9 ...
10 }
(gdb) record function-call-history /ilc
1 bar inst 1,4 at foo.c:6,8
2 foo inst 5,10 at foo.c:2,3
3 bar inst 11,13 at foo.c:9,10
Before using it you need to run:
start
record btrace
which is where a non capable CPU fails with:
Target does not support branch tracing.
CPU support is further discussed at: How to run record instruction-history and function-call-history in GDB?
Related threads:
how to trace function call in C?
Is there a compiler feature to inject custom function entry and exit code?
For embedded, you also consider JTAG and supporting hardware like ARM's DSTREAM, but x86 support does not seem very good: debugging x86 kernel using a hardware debugger
This question might need clarification to decide between what are currently 2 answers. Depends on what you need:
1) You need to know how many times each function is being called in straight list/graph format of functions matched with # of calls. This could lead to ambiguous/inconclusive results if your code is not procedural (i.e. functions calling other functions in a branch out structure without ambiguity of what is calling what). This is basic gprof functionality which requires recompilation with -pg flag.
2) You need a list of functions in the order in which they were called, this depends on your program which is the best/feasible option:
a) IF your program runs and terminates without runtime errors you can use gprof for this purpose.
b) ELSE option above using dbg with logging and break points is the left over option that I learned upon reading this.
3) You need to know not only the order but, for example, the function arguments for each call as well. My current work is simulations in physics of particle transport, so this would ABSOLUTELY be useful in tracking down where anomalous results are coming from... i.e. when the arguments getting passed around stop making sense. I imagine one way to do this is would be a variation on what Employed Russian did except using the following:
(gdb) info args
Logging the results of this command with every break point (set at every function call) gives the args of the current function.
With gdb, if you can find the most child function, you can list its all ancestors like this:
gdb <your-binary>
(gdb) b theMostChildFunction ## put breakpoint on the desired function
(gdb) r ## run the program
(gdb) bt ## backtrace starting from the breakpoint
Otherwise, on linux, you can use perf tool to trace programs and their function calls. The advantage of this, it is tracing all processes including child processes and also it shows usage percentages of the functions in the program.
You can install perf like this:
sudo apt install linux-tools-generic
sudo apt install linux-cloud-tools-generic
Before using perf you may also need to remove some kernel restrictions temporarily:
sudo sh -c 'echo 0 >/proc/sys/kernel/kptr_restrict'
sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
sudo sh -c 'echo 0 >/proc/sys/kernel/yama/ptrace_scope'
After this, you can run your program binary with perf like this:
perf record -g -s -a <your-binary-and-its-flags>
Then either you can look the output on terminal like this:
perf report
or on text file like this:
perf report -i perf.data > output.txt
vim output.txt
when you are recording the function calls with perf also you may want to filter kernel calls with --all-user flag:
perf record -g -s -a --all-user <your-binary-and-its-flags>
For further information you can look here: https://perf.wiki.kernel.org/index.php/Tutorial