I am trying to write a program in C (in Linux 64bit with GCC 4.1.2).
int program_instances(char *cmdname)
{
char buf[32], *ret;
char cmdbuf[512];
FILE *cmdpipe;
sprintf(cmdbuf, "/bin/ps -eo comm | /bin/grep -c '%s'",
cmdname);
cmdpipe = popen(cmdbuf, "r");
if (!cmdpipe)
{
return -1;
}
memset(buf, 0, sizeof(buf));
ret = fgets(buf, sizeof(buf), cmdpipe);
pclose(cmdpipe);
if (!ret)
{
return -1;
}
int nr = atoi(buf);
return nr;
}
Tried to debug the issue through gdb but after the line
sprintf(cmdbuf, "/bin/ps -eo comm | /bin/grep -c '%'",cmdname);
The programm is not crossing the above line , throwing the below lines..
Executing new program: /bin/bash
Error in re-setting breakpoint 1: No symbol table is loaded. Use the "file" command.
[New process 2437]
Executing new program: /bin/ps
Please help us to resolve this issue.
Try to compile your code with -g and remove -O [compiler flag]. When optimizing compiler(gcc) changes order of instructions to improve speed. After recompiling attach debugger again.
Related
I'm trying to use ffmpeg to do some operations for me. It's really simple for now. I want to omit the ffmpeg output in my console, either redirecting them to strings or a .txt file that I can control. I'm on Windows 10.
I have tried _popen (with and "r" and "w") and system("ffmpeg command > output.txt")', with no success.
#include <iostream>
#include <stdio.h>
using namespace std;
#define BUFSIZE 256
int main()
{
/* 1.
x = system("ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4 > output.txt");
*/
/* 2.
FILE* p;
p = _popen("ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4", "w");
_pclose(p);
*/
/* 3.
char cmd[200] = { "ffmpeg -i video.mp4 -i audio.mp4 -c copy output.mp4" };
char buf[BUFSIZE];
FILE* fp;
if ((fp = _popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
// printf("OUTPUT: %s", buf);
}
if (_pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
*/
return 0;
}
Further in the development, I would like to know when the ffmpeg process finished (maybe I can monitor the ffmpeg return value?) or to display only the last line if the some error occurred.
I have made it to work.
In the solution 1, I added " 2>&1" to the end of the string.
Found it here: ffmpeg command line write output to a text file
output-to-a-text-file
Thanks!
We have a piece of legacy code that uses Flex with C-style FILE* descriptors. To support reading compressed files into Flex, we extended the "open" semantics to open gzip'ed files using
FILE* file = popen("gzip -cd <filename>");
rather than fopen.
We've encountered some problems recently where attempting this across a unix filesystem (probably another filesystem mounted using NFS on a NetApp) causes this entire code stream to crash (segfault), the first message we see is
gzip: stdout: Broken Pipe
and our own crash frame.
If we take the file and move it to the local filesystem where the process is running, there is no segfault and everything works as normal.
What have we tried to replicate or fix?
read files compressed using gzip/ bzip2 etc from internal test NFS filesystems
verify that the target file can be opened
"open" the file and read a few bytes to make sure it can be opened by this process
All of this succeeds and yet we still encounter the crash.
We are out of ideas and could use some suggestions.
Sam Appleton
When you test it, SIGPIPE has its default action (kill the gzip process). When the process runs on your client's side, SIGPIPE is masked. Here's a minimal program that reproduces the error:
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#define SZ 4096
void mask()
{
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sa.sa_flags = 0;
if (-1 == sigaction(SIGPIPE, &sa, 0))
{
perror("sigaction");
exit(1);
}
}
int main(int argc, char ** argv)
{
char buf[SZ];
#ifdef MASK
mask();
#endif
FILE * f = popen("gzip -dc foo.gz", "r");
if (0 != fread(buf, SZ, 1, f))
{
fwrite(buf, SZ, 1, stdout);
}
fprintf(stderr, "%d\n", pclose(f));
}
And here's the output with and without MASK:
$ gcc -o foo foo.c
$ gcc -DMASK -o foomask foo.c
$ /foo > /dev/null
13
$ /foomask > /dev/null
gzip: stdout: Broken pipe
256
$
In short, it has nothing to do with NFS. That's a red herring.
Working on Linux am trying to build a Crash Handler function - so as before crashing we get stack trace in log file -
done some study and came to know,its done either using -g/-rdynamic Flags to generate debug info then use glibc backtrace / backtrace_symbols_fd functions to get stack trace ...
Its not much of use as in my app, am not allowed to use -g/-rdynamic flags ..
so reading further reading
I have build the following code which is not working as expected and in generated log file it ends in following error :
(gdb) Hangup detected on fd 0
error detected on stdin
A debugging session is active.
Inferior 1 [process 6625] will be detached.
Quit anyway? (y or n) [answered Y; input not from terminal]
Detaching from program: /u/vivek/demo/testprg, process 6625
Code:
Register a Crash Handler function at startup as -
struct sigaction act;
memset(&act, 0, sizeof (act));
act.sa_sigaction = ProcessCrash;
sigfillset (&act.sa_mask);
act.sa_flags = SA_SIGINFO;
sigaction (SIGSEGV, &act, NULL);
Following function called when my program receives SIGSEGV signal -
void ProcessCrash( int signal, siginfo_t * siginfo, void *context)
{
cerr <<"** ProcessCrash –Handler Function**" << endl;
ucontext_t *uc = (ucontext_t *)context;
if (signal == SIGSEGV)
fprintf(stderr, "\nGot signal %d, faulty address is %p, "
"from %p\n\n", signal, siginfo->si_addr,
uc->uc_mcontext.gregs[REG_RIP]); // REG_EIP is changed to REG_RIP for –m64 arch.
else
fprintf(stderr, "Got signal %d#92;\n", signal);
// [[ using GDB to pring the stack trace
char gdb[516];
// command 1
//sprintf(gdb, "echo 'where\ndetach' | gdb -q %.256s -pid %d > gdbTest.dump", program_invocation_name, getpid());
// command 2
sprintf(gdb, "(echo \"source Trace.txt\";cat) | gdb -q %.256s -pid %d > gdbTest.dump", program_invocation_name, getpid());
fprintf(stderr, "\n** GDB Command-> %s \n", gdb);
// output of above is
// ** GDB Command-> (echo "source Trace.txt";cat) | gdb -q /u/vivek/demo/testprg -pid 6625 > gdbTest.dump
// Run Either command 1 or command 2 but we get the same result
system(gdb);
// GDB test ]]
// Produce a core dump
abort();
return;
}
Trace.txt contents:
set logging on
where
detach
quit
Please let me know is there a way out of it ... as I am not getting ideas to overcome it ..
Not sure what you intended to do with the (echo \"source Trace.txt\";cat) | part.
Simply using gdb -batch -x Trace.txt -q %.256s -pid %d > gdbTest.dump works fine as far as I can tell.
Perl 5.14 source - Sample program failing
I'm trying to execute the below program on Linux 64 with libperl.so built with 5.14 source
and i'm getting an abort in the location
Program terminated with signal 11, Segmentation fault.
#0 0x00002abdc0eb2656 in Perl_sv_2mortal () from ./libperl.so
(gdb) where
#0 0x00002abdc0eb2656 in Perl_sv_2mortal () from ./libperl.so
#1 0x00000000004010ed in PerlPower ()
#2 0x0000000000401335 in main ()
(gdb)
My program:
#include <EXTERN.h>
#include <perl.h>
#include <stdio.h>
static PerlInterpreter *my_perl;
static void PerlPower(int a, int b)
{
dSP; /* initialize stack pointer */
ENTER; /* everything created after here */
SAVETMPS; /* ...is a temporary variable. */
PUSHMARK(SP); /* remember the stack pointer */
XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */
XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */
PUTBACK; /* make local stack pointer global */
call_pv("expo", G_SCALAR); /* call the function */
SPAGAIN; /* refresh stack pointer *
/* pop the return value from stack */
printf("%d to the %dth power is %d.\n", a, b, POPi);
PUTBACK;
FREETMPS; /* free that return value */
LEAVE; /* ...and the XPUSHed "mortal" args. */
}
int main(int argc, char **argv, char **env)
{
char *my_argv[] = { "", "power.pl" };
PERL_SYS_INIT3(&argc, &argv, &env);
my_perl = perl_alloc();
perl_construct(my_perl);
perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
perl_run(my_perl);
PerlPower(3, 4);
/*** Compute 3 ** 4 ***/
perl_destruct(my_perl);
perl_free(my_perl);
PERL_SYS_TERM();
}
power.pl contains the below statements
sub expo {
my ($a, $b) = #_;
return $a ** $b;
}
The above sample C and perl program was taken from the link http://perldoc.perl.org/perlembed.html#Evaluating-a-Perl-statement-from-your-C-program
I'm using the below compiler options
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -Wdeclaration-after-statement -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2 -fmessage-length=0 -Wall -D_FORTIFY_SOURCE=2 -g -Wall -pipe',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -fno-strict-aliasing -pipe -Wdeclaration-after-statement'
ccversion='', gccversion='4.1.2 20070115 (prerelease) (SUSE Linux)', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Can you please help me to narrow down the problem?
I got one too, I got the win32 equivalent Faulting application power.exe, version 0.0.0.0, faulting module perl514.dll, version 0.0.0.0, fault address 0x000c155f.
but I also got an error message :)
$ power.exe
Can't open perl script "power.pl": No such file or directory
After copying power.pl from embed it works as expected
$ cat power.pl
sub expo {
my ($a, $b) = #_;
return $a ** $b;
}
$ power.exe
3 to the 4th power is 81.
The problem was while compiling the source i hadn't specified the new 5.14.2 header files location. I copied both the c and perl file to the folder containing new header file of 5.14.2 and compiling with below options resolved the problem
g++ -o test_perl test_perl.c -I . -L . -g perl -MExtUtils::Embed -e ccopts -e ldopts
LD_LIBRARY_PATH=.:LD_LIBRARY_PATH;export LD_LIBRARY_PATH
So this is probably a long shot, but is there any way to run a C or C++ file as a script? I tried:
#!/usr/bin/gcc main.c -o main; ./main
int main(){ return 0; }
But it says:
./main.c:1:2: error: invalid preprocessing directive #!
Short answer:
//usr/bin/clang "$0" && exec ./a.out "$#"
int main(){
return 0;
}
The trick is that your text file must be both valid C/C++ code and shell script. Remember to exit from the shell script before the interpreter reaches the C/C++ code, or invoke exec magic.
Run with chmod +x main.c; ./main.c.
A shebang like #!/usr/bin/tcc -run isn't needed because unix-like systems will already execute the text file within the shell.
(adapted from this comment)
I used it in my C++ script:
//usr/bin/clang++ -O3 -std=c++11 "$0" && ./a.out; exit
#include <iostream>
int main() {
for (auto i: {1, 2, 3})
std::cout << i << std::endl;
return 0;
}
If your compilation line grows too much you can use the preprocessor (adapted from this answer) as this plain old C code shows:
#if 0
clang "$0" && ./a.out
rm -f ./a.out
exit
#endif
int main() {
return 0;
}
Of course you can cache the executable:
#if 0
EXEC=${0%.*}
test -x "$EXEC" || clang "$0" -o "$EXEC"
exec "$EXEC"
#endif
int main() {
return 0;
}
Now, for the truly eccentric Java developer:
/*/../bin/true
CLASS_NAME=$(basename "${0%.*}")
CLASS_PATH="$(dirname "$0")"
javac "$0" && java -cp "${CLASS_PATH}" ${CLASS_NAME}
rm -f "${CLASS_PATH}/${CLASS_NAME}.class"
exit
*/
class Main {
public static void main(String[] args) {
return;
}
}
D programmers simply put a shebang at the beginning of text file without breaking the syntax:
#!/usr/bin/rdmd
void main(){}
See:
https://unix.stackexchange.com/a/373229/23567
https://stackoverflow.com/a/12296348/199332
For C, you may have a look at tcc, the Tiny C Compiler. Running C code as a script is one of its possible uses.
$ cat /usr/local/bin/runc
#!/bin/bash
sed -n '2,$p' "$#" | gcc -o /tmp/a.out -x c++ - && /tmp/a.out
rm -f /tmp/a.out
$ cat main.c
#!/bin/bash /usr/local/bin/runc
#include <stdio.h>
int main() {
printf("hello world!\n");
return 0;
}
$ ./main.c
hello world!
The sed command takes the .c file and strips off the hash-bang line. 2,$p means print lines 2 to end of file; "$#" expands to the command-line arguments to the runc script, i.e. "main.c".
sed's output is piped to gcc. Passing - to gcc tells it to read from stdin, and when you do that you also have to specify the source language with -x since it has no file name to guess from.
Since the shebang line will be passed to the compiler, and # indicates a preprocessor directive, it will choke on a #!.
What you can do is embed the makefile in the .c file (as discussed in this xkcd thread)
#if 0
make $# -f - <<EOF
all: foo
foo.o:
cc -c -o foo.o -DFOO_C $0
bar.o:
cc -c -o bar.o -DBAR_C $0
foo: foo.o bar.o
cc -o foo foo.o bar.o
EOF
exit;
#endif
#ifdef FOO_C
#include <stdlib.h>
extern void bar();
int main(int argc, char* argv[]) {
bar();
return EXIT_SUCCESS;
}
#endif
#ifdef BAR_C
void bar() {
puts("bar!");
}
#endif
The #if 0 #endif pair surrounding the makefile ensure the preprocessor ignores that section of text, and the EOF marker marks where the make command should stop parsing input.
CINT:
CINT is an interpreter for C and C++
code. It is useful e.g. for situations
where rapid development is more
important than execution time. Using
an interpreter the compile and link
cycle is dramatically reduced
facilitating rapid development. CINT
makes C/C++ programming enjoyable even
for part-time programmers.
You might want to checkout ryanmjacobs/c which was designed for this in mind. It acts as a wrapper around your favorite compiler.
#!/usr/bin/c
#include <stdio.h>
int main(void) {
printf("Hello World!\n");
return 0;
}
The nice thing about using c is that you can choose what compiler you want to use, e.g.
$ export CC=clang
$ export CC=gcc
So you get all of your favorite optimizations too! Beat that tcc -run!
You can also add compiler flags to the shebang, as long as they are terminated with the -- characters:
#!/usr/bin/c -Wall -g -lncurses --
#include <ncurses.h>
int main(void) {
initscr();
/* ... */
return 0;
}
c also uses $CFLAGS and $CPPFLAGS if they are set as well.
#!/usr/bin/env sh
tail -n +$(( $LINENO + 1 )) "$0" | cc -xc - && { ./a.out "$#"; e="$?"; rm ./a.out; exit "$e"; }
#include <stdio.h>
int main(int argc, char const* argv[]) {
printf("Hello world!\n");
return 0;
}
This properly forwards the arguments and the exit code too.
Quite a short proposal would exploit:
The current shell script being the default interpreter for unknown types (without a shebang or a recognizable binary header).
The "#" being a comment in shell and "#if 0" disabling code.
#if 0
F="$(dirname $0)/.$(basename $0).bin"
[ ! -f $F -o $F -ot $0 ] && { c++ "$0" -o "$F" || exit 1 ; }
exec "$F" "$#"
#endif
// Here starts my C++ program :)
#include <iostream>
#include <unistd.h>
using namespace std;
int main(int argc, char **argv) {
if (argv[1])
clog << "Hello " << argv[1] << endl;
else
clog << "hello world" << endl;
}
Then you can chmod +x your .cpp files and then ./run.cpp.
You could easily give flags for the compiler.
The binary is cached in the current directory along with the source, and updated when necessary.
The original arguments are passed to the binary: ./run.cpp Hi
It doesn't reuse the a.out, so that you can have multiple binaries in the same folder.
Uses whatever c++ compiler you have in your system.
The binary starts with "." so that it is hidden from the directory listing.
Problems:
What happens on concurrent executions?
Variatn of John Kugelman can be written in this way:
#!/bin/bash
t=`mktemp`
sed '1,/^\/\/code/d' "$0" | g++ -o "$t" -x c++ - && "$t" "$#"
r=$?
rm -f "$t"
exit $r
//code
#include <stdio.h>
int main() {
printf("Hi\n");
return 0;
}
Here's yet another alternative:
#if 0
TMP=$(mktemp -d)
cc -o ${TMP}/a.out ${0} && ${TMP}/a.out ${#:1} ; RV=${?}
rm -rf ${TMP}
exit ${RV}
#endif
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("Hello world\n");
return 0;
}
I know this question is not a recent one, but I decided to throw my answer into the mix anyways.
With Clang and LLVM, there is not any need to write out an intermediate file or call an external helper program/script. (apart from clang/clang++/lli)
You can just pipe the output of clang/clang++ to lli.
#if 0
CXX=clang++
CXXFLAGS="-O2 -Wall -Werror -std=c++17"
CXXARGS="-xc++ -emit-llvm -c -o -"
CXXCMD="$CXX $CXXFLAGS $CXXARGS $0"
LLICMD="lli -force-interpreter -fake-argv0=$0 -"
$CXXCMD | $LLICMD "$#" ; exit $?
#endif
#include <cstdio>
int main (int argc, char **argv) {
printf ("Hello llvm: %d\n", argc);
for (auto i = 0; i < argc; i++) {
printf("%d: %s\n", i, argv[i]);
}
return 3==argc;
}
The above however does not let you use stdin in your c/c++ script.
If bash is your shell, then you can do the following to use stdin:
#if 0
CXX=clang++
CXXFLAGS="-O2 -Wall -Werror -std=c++17"
CXXARGS="-xc++ -emit-llvm -c -o -"
CXXCMD="$CXX $CXXFLAGS $CXXARGS $0"
LLICMD="lli -force-interpreter -fake-argv0=$0"
exec $LLICMD <($CXXCMD) "$#"
#endif
#include <cstdio>
int main (int argc, char **argv) {
printf ("Hello llvm: %d\n", argc);
for (auto i = 0; i < argc; i++) {
printf("%d: %s\n", i, argv[i]);
}
for (int c; EOF != (c=getchar()); putchar(c));
return 3==argc;
}
There are several places that suggest the shebang (#!) should remain but its illegal for the gcc compiler. So several solutions cut it out. In addition it is possible to insert a preprocessor directive that fixes the compiler messages for the case the c code is wrong.
#!/bin/bash
#ifdef 0
xxx=$(mktemp -d)
awk 'BEGIN
{ print "#line 2 \"$0\""; first=1; }
{ if (first) first=0; else print $0 }' $0 |\
g++ -x c++ -o ${xxx} - && ./${xxx} "$#"
rv=$?
\rm ./${xxx}
exit $rv
#endif
#include <iostream>
int main(int argc,char *argv[]) {
std::cout<<"Hello world"<<std::endl;
}
As stated in a previous answer, if you use tcc as your compiler, you can put a shebang #!/usr/bin/tcc -run as the first line of your source file.
However, there is a small problem with that: if you want to compile that same file, gcc will throw an error: invalid preprocessing directive #! (tcc will ignore the shebang and compile just fine).
If you still need to compile with gcc one workaround is to use the tail command to cut off the shebang line from the source file before piping it into gcc:
tail -n+2 helloworld.c | gcc -xc -
Keep in mind that all warnings and/or errors will be off by one line.
You can automate that by creating a bash script that checks whether a file begins with a shebang, something like
if [[ $(head -c2 $1) == '#!' ]]
then
tail -n+2 $1 | gcc -xc -
else
gcc $1
fi
and use that to compile your source instead of directly invoking gcc.
Just wanted to share, thanks to Pedro's explanation on solutions using the #if 0 trick, I have updated my fork on TCC (Sugar C) so that all examples can be called with shebang, finally, with no errors when looking source on the IDE.
Now, code displays beautifully using clangd in VS Code for project sources. Samples first lines look like:
#if 0
/usr/local/bin/sugar `basename $0` $# && exit;
// above is a shebang hack, so you can run: ./args.c <arg 1> <arg 2> <arg N>
#endif
The original intention of this project always has been to use C as if a scripting language using TCC base under the hood, but with a client that prioritizes ram output over file output (without the of -run directive).
You can check out the project at: https://github.com/antonioprates/sugar
I like to use this as the first line at the top of my programs:
For C (technically: gnu C as I've specified it below):
///usr/bin/env ccache gcc -Wall -Wextra -Werror -O3 -std=gnu17 "$0" -o /tmp/a -lm && /tmp/a "$#"; exit
For C++ (technically: gnu++ as I've specified it below):
///usr/bin/env ccache g++ -Wall -Wextra -Werror -O3 -std=gnu++17 "$0" -o /tmp/a -lm && /tmp/a "$#"; exit
ccache helps ensure your compiling is a little more efficient. Install it in Ubuntu with sudo apt update && sudo apt install ccache.
For Go (golang) and some explanations of the lines above, see my other answer here: What's the appropriate Go shebang line?