Prettify clang -v output - c++

Is there any way to get clang output to insert carriage returns? When compiling with the verbose option, I just get these huge unreadable dumps of compiler flags and paths.

Use popen to start your clang session. Create a new command line as clang -v (including the space) and concatenate the arguments that you usually feed to clang itself. After the final argument, add 2>&1 to convert Clang's stderr output to regular stdout so popen can pick it up. Then loop over popen's input and parse each separate line, adding extra information where you see fit.
As an example, I grabbed the entire set of flags for my local Clang using
clang -cc1 --help
and incorporated this as a single long string in my C program. Then I looped over the return results from popen, scanning for flags starting with -, and when one was found, I scanned the long flags string for this. If it found something, I write it out on a separate line in green (using ANSI escape sequences). Then I test the flags string if an argument should follow – these usually have a leading <...> indicator. If so, I write it out in blue. Finally, I write out the entire flag explanation line until I encounter an end-of-line.
With my very rough program called colorclang – 123 lines of actual code – I get output like this:
As it is, it tests every input line for possible flags so there is some mis-coloring. More exact parsing is possible; I'd have to add separate routines for the single line starting with "/usr/bin/clang" (for the common Clang flags), the single line starting with "/usr/bin/ld" (and parse the loader flags), and possibly the lines after each #include .. statement.
Pieced together with the help of Complete list of clang flags?, Steve Kemp's answer to C: Run a System Command and Get Output?, and after deducing clang -v writes to stderr, larsman's answer to c popen won't catch stderr.

Related

Passing a angled bracket as a command-line argument input while debugging

I'm writing a brainfuck interpreter in NASM, where code is supplied as a command line argument to the program. I'm trying to test looping, but GDB doesn't like my input. For example, this executes error-free when run on its own:
$./interpret "+++++[->+<]"
It hangs indefinitely, but I think that that's due to a bug in the looping logic in the interpreter (thus GDB).
If I load interpret into GDB though and attempt to supply the same argument, I get complaints:
gef➤ start "+++++[->+<]"
/bin/bash: line 1: ]: No such file or directory
/bin/bash: line 1: ]: No such file or directory
This seems to be due to < being interpreted as redirection despite the quotes, since [] works fine in GDB.
I tried escaping the STDIN redirection with \<, but that leads to the same error, and <<, but that leads to a warning:
gef➤ start "+++++[->+<<]"
/bin/bash: line 1: warning: here-document at line 1 delimited by end-of-file (wanted `]')
And the code gets cut off:
$r15 : 0x00007fffffffe428 → 0x002d5b2b2b2b2b2b ("+++++[-"?)
Is there a way to have GDB take what I give literally to start, and not attempt to do any redirection/interpretation of the arguments?
Is there a way to have GDB take what I give literally to start, and not attempt to do any redirection/interpretation of the arguments?
GDB isn't doing any interpretation, bash does. Using single-quotes instead of double-quotes may fix that.
(I wasn't able to replicate the problem using GDB-10.0 and bash-5.1.4 with double quotes though.)

Why does using system("some.exe") in C++ method not work like the command line?

I am writing a program for Windows that eventually has to launch a different pre-existing .exe that sits on the same computer. It passes multiple parameters to this .exe file. I am reading the actual command and parameters and constructing the command but I also tried hard coding it with the same results. Here's the hard coded version (I picked this out of an older C program that uses the same.exe):
system("c://IQapture//dmon2_6_IHD -p2 c://IQapture//mon_table_101_Tx8.txt 11 0 0");
So in the original program inside int _cdecl main(int argc, char**argv) this use of system works. In my C++ program inside a C++ class method when I issue the command the correct program launches but it immediately puts up an error dialog stating that an error has occurred. I echo'd the system string used to launch the exe out to the console. Right after it fails, I copy and paste the same line that was echo'd and this time the exe runs without error. This is repeatable. In case it was timing related I tried adding a 10 second delay before issuing the system command but it didn't matter. Plus the original older program doesn't require a delay. This implies to me that the string is correct and the target program works. Somehow the system() invocation is different from a direct command line invocation. The program compiles and builds fine. I'm using Visual Studio 2010.
Does anyone have ideas on how to make the system() invocation work like the command line invocation?
That really doesn't look like the kind of thing that Windows would be happy with... Try it with backslashes instead:
system("c:\\IQapture\\dmon2_6_IHD -p2 c:\\IQapture\\mon_table_101_Tx8.txt 11 0 0");
If that still doesn't work, you quite likely have one of the following issues:
Your current working directory is wrong;
An environment variable is missing;
Your program is running with the wrong user permissions;
Your program is tying up a resource that the spawned process requires (eg you have not closed a file that it requires as input).
There are a lot of things to consider - the environment, the user running the program, the parent process and what's inherited... Take a look at the parameters to the CreateProcess function. Chances are your system call's invocation isn't matching the command line's (though that may not be the issue, simpler things are more likely.)
I'd advise working backwards from the error to rule out simple causes such as the environment, current directory, etc. before delving into such things as creation flags and security attributes.
You have your slashes backwards. Try:
system("c:/IQapture/dmon2_6_IHD -p2 c:/IQapture/mon_table_101_Tx8.txt 11 0 0");
You can use the backslash \ but because that is an escape sequence starter in a string (for C/C++) that is why you use two in a row. As the compiler will convert \\ into a single slahs in the string:
Thus:
system("c:\\IQapture\\dmon2_6_IHD -p2 c:\\IQapture\\mon_table_101_Tx8.txt 11 0 0");
// Is equivelent to the command line string:
> c:\IQapture\dmon2_6_IHD -p2 c:\IQapture\mon_table_101_Tx8.txt 11 0 0
But Windows has supported both types of slashes for longer than I can remember. So the following command line is equivalent.
> c:/IQapture/dmon2_6_IHD -p2 c:/IQapture/mon_table_101_Tx8.txt 11 0 0
Using '/' in a string (in C/C++) does not require escaping. So you just need to use it as is:
system("c:/IQapture/dmon2_6_IHD -p2 c:/IQapture/mon_table_101_Tx8.txt 11 0 0");

gdb input redirection using cygwin

It seems that input redirection in gdb does not work in Cygwin e.g
(gdb) run < input.txt
Is there other way to redirect input in gdb of Cygwin??
Unfortunately this is not possible when running gdb in cygwin. The bug exists for a quote long time, but apparently it's a hard one to fix - and probably the gdb devs prefer spending time on features/issues relevant to more common environments (such as Linux).
There are various possible workarounds; I'd prefer the first one since it's the cleanest and also useful while not debugging / running on cygwin:
Add a command line argument, e.g. -f whatever with whatever being the filename to read from. If the argument is not present or set to -, read from stdin. The -f - option is optional of course but for arguments accepting filenames it's a common standard (as long as it makes sense) to handle - as "use stdin/out".
Use the gdb hack mentioned here to remap stdin to a manually opened file inside the application:
> gdb yourexecutable
(gdb) break main
(gdb) run
(gdb) call dup2(open("input.txt", 0), 0)
(gdb) continue
This sets a breakpoint on the main function, then executes the program which will break right after entering main. Then dup2 is used to replace the stdin fd (0) with a file descriptor of the input file.

How to properly use system() to execute a command in C++?

I am new to C++ programming under Windows. I am trying to execute a command say cuobjdump in C++ code using the system() function:
system("C:\\program files\\nvidia gpu computing...\\cuobjdump.exe --dump-cubin C:\\..\\input.exe");
output:
Usage : cuobjdump [options] <file>
This followed by the list of the options for cuobjdump.
When I execute this program I always get the cuobjdump help options displayed in the command line. It's as if the system call does not parse the filename. What am I doing wrong? I get the same result while using createprocess. The options --dump-cubin gives an error as if I mistyped it.
Give a try with (that is, surrounding cuobjdump.exe path with ", properly escaped in C++ as \"):
system("\"C:\\program files\\nvidia gpu computing...\\cuobjdump.exe\" --dump-cubin C:\\..\\input.exe");
system("cuobjdump --dump-cubin path\filename.exe");
That \f is interpreted by the compiler as a string escape sequence, try path\\filename.exe
Most obviously, \ is an escape character in C / C++ strings, so it has to be doubled if you want to use it literally.
system("cuobjdump --dump-cubin path\\filename.exe");
Assuming that path is correct, you have to use a double \\ within strings to represent a single \.
I suggest you to use CreateProcess, or ShellExecute / ShellExecuteEx since you are working on Windows. system and ShellExecute eventually calls CreateProcess only.

Can system() return before piped command is finished

I am having trouble using system() from libc on Linux. My code is this:
system( "tar zxvOf some.tar.gz fileToExtract | sed 's/some text to remove//' > output" );
std::string line;
int count = 0;
std::ifstream inputFile( "output" );
while( std::getline( input, line != NULL ) )
++count;
I run this snippet repeatedly and occasionally I find that count == 0 at the end of the run - no lines have been read from the file. I look at the file system and the file has the contents I would expect (greater than zero lines).
My question is should system() return when the entire command passed in has completed or does the presence of the pipe '|' mean system() can return before the part of the command after the pipe is completed?
I have explicitly not used a '&' to background any part of the command to system().
To further clarify I do in practice run the code snippet multiples times in parallel but the output file is a unique filename named after the thread ID and a static integer incremented per call to system(). I'm confident that the file being output to and read is unique for each call to system().
According to the documentation
The system() function shall not return until the child process has terminated.
Perhaps capture the output of "output" when it fails and see what it is? In addition, checking the return value of system would be a good idea. One scenario is that the shell command you are running is failing and you aren't checking the return value.
system(...) calls the standard shell to execute the command, and the shell itself should return only after the shell has regained control over the terminal. So if there's one of the programs backgrounded, system will return early.
Backgrounding happens through suffixing a command with & so check if the string you pass to system(...) contains any & and if so make sure they're properly quoted from shell processing.
System will only return after completion of its command and the file output should be readable in full after that. But ...
... multiple instances of your code snippet run in parallel would interfere because all use the same file output. If you just want to examine the contents of output and do not need the file itself, I would use popen instead of system. popen allows you to read the output of the pipe via a FILE*.
In case of a full file system, you could also see an empty output while the popen version would have no trouble with this condition.
To notice errors like a full file system, always check the return code of your calls (system, popen, ...). If there is an error the manpage will tell you to check errno. The number errno can be converted to a human readable text by strerror and output by perror.