How can I count syscalls in a Go program on OS X? - c

I'm trying to count the syscalls in my Go program on OS X Yosemite. I've tried using dtruss and dtrace, but both cause my program to crash with the following error, followed by a stack trace:
fatal error: runtime: bsdthread_register error
The two commands I've used are:
sudo dtruss "./my_program my_arg"
sudo dtrace -c "powerset 2" -n 'syscall:::entry { #num[probefunc] = count(); }'
Things I've Tried
The main takeaway from my Google-foo has been to unset DYLD_INSERT_LIBRARIES, which I have done numerous times to no avail.
./my_program is a binary that I created with go install. I've written an equivalent C program and both of the above commands work fine with that.

If you want to use dtrace on macOS, you will need to use the external linker to build your program
-ldflags -linkmode=external

Related

How to get debugging symbols when compiling with clang on Windows

I am having trouble getting the debugger to work properly when setting up clang on my Windows 10 machine. Compilation seems to work OK, at least for the simple "hello, world" program I tried. However, when I try to run the lldb or gdb debuggers on this test program (or any other program I tried), it does not recognize function names.
Here's my C program code:
#include <stdio.h>
int main(void) {
puts("Hello, world!");
return 0;
}
Nothing too spectacular here, I know. I'm compiling with the following command:
> clang -g -O0 hello.c -o hello.exe
I then try to run the debugger:
> lldb hello
(lldb) target create "hello"
Current executable set to 'hello' (x86_64).
(lldb) b main
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) r
Process 12156 launched: 'C:\Users\********\Projects\clang-test\hello.exe' (x86_64)
Process 12156 exited with status = 0 (0x00000000)
(lldb)
Apparently the symbol "main" was not recognized, and the program did not halt at the start of the "main" function but ran to completion (in a different console window, hence no program output here).
How do I get debugging symbols to work? In a different stackoverflow answer I found that adding compiler options "-g -O0" should do the trick, but as you can see that does not solve the problem for me. I also found a different stackoverflow answer about how to set up debugging if the code is not in the same directory as the executable, but that is not relevant to my case: the current working directory is the same as the directory with the code and executable in them.
Some version information:
> clang --version
clang version 9.0.0 (tags/RELEASE_900/final)
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
> lldb --version
lldb version 9.0.0
The "-g -O0" options you provided should indeed let the debugger know all the symbols it needs from the executable.
Therefore, I suspect the problem is elsewhere, perhaps with your terminal, or your version/implementation of LLDB.
Are you using the windows cmd.exe commandline ? or something else, like Powershell ?
I've never managed to get debuggers working properly in those environments, but it was much easier with Cygwin, which is a bash shell for windows (it creates a "simulated" linux environment within its install folder, so you have all the /usr,/bin,/etc folders a bash shell needs)
This way you can actually use gdb the way you would on a UNIX system.
If the above method sounds like more of a hassle than a time-gain, then yeah I would recommend another debugger altogether, like the Visual Studio debugger.
In fact, maybe a memory-analysis tool like Dr.Memory can give you what you need

How to know if a C program supports an option

I'm developing a script that checks the version of some installed C programs. The version check is performed with the --version option. However, this option may not be implemented in all the checked programs. When the option is implemented I use:
version=$(./$program_name --version)
But when it's not, the program just starts executing.
If I just execute the program in the background and the stop it if continues running, I can never get the version number. Is there a way to check whether the option is implemented without letting the program run?
Not completely waterproof but I nice start is using strings:
strings /usr/bin/git | grep -- --version
If you are referring to any arbitrary C program, no there is currently no way to reliably check if a program supports an option. You can try guessing with a mixture of ./program --help, ./program --usage, ./program -h and ./program --this-option-is-a-lie-or-some-other-bogus-option-to-give-usage-information. However, it all ultimately boils down to guesswork.
On RedHat and derivates using yum and rpm you can ask the rpm package manager:
$ rpm -q --whatprovides /bin/cat
coreutils-8.4-31.el6_5.1.i686
On Debian and derivated using apt-get you can ask the APT package manager:
$ dpkg-query -S /bin/bash
bash: /bin/bash
Back in the day we always included a what string with version info. Actually part of SCCS, if the program contained strings starting with "#(#)", it is displayed by the what command. C code would like like this:
static char prog_id[] = "#(#) my_program version 1.0 - 3/26/2014";
Anyway try doing a what on the program and see what you get. heh.

Getting locale functions to work in glibc

I need to make some modifications to the the C standard library (glibc) in order to get some performance improvements. Specifically, I am going to be writing some specialized versions of some of the locale-dependent functions (which in glibc perform poorly), such as strcoll.
I have checked out the glibc source from here, into ~/Desktop/glibc. I then ran the following sequence of commands without error.
$ cd ~/Desktop
$ mkdir bglibc
$ cd bglibc
$ ./../glibc/configure --prefix=~/Desktop/bglibc
$ make
$ make install
At this point, I have successfully compiled and installed glibc into ~/Desktop/bglibc. I then created the following test program (ct.c) in the bglibc directory:
#include <stdio.h>
#include <locale.h>
int main ()
{
char *locale = NULL;
locale = "en_US.utf8";
char *result = setlocale(LC_COLLATE, locale);
if (result == NULL) {
printf("locale not set\n");
}
printf("strcoll: %d\n", strcoll("some", "string"));
return 0;
}
I then build it with this script:
iSYSROOT=~/Desktop/bglibc
gcc -o ct ct.c \
--sysroot=${SYSROOT} \
-Wl,-rpath=${SYSROOT}/lib \
-Wl,--dynamic-linker=${SYSROOT}/lib/ld.so.1
Which builds it properly. I then run it with this script:
#!/bin/sh
builddir=`dirname "$0"`
GCONV_PATH="${builddir}/iconvdata" \
exec "${builddir}"/elf/ld-linux-x86-64.so.2 --library-path "${builddir}":"${builddir}"/*:"${builddir}"/*/*:"${builddir}"/*/*/* ${1+"$#"}
Which is names testrun.sh. To run it on the program I previously compiled (ct), I run ./testrun.sh ./ct.
This successfully runs the program, however the program prints out locale not set, meaning that it was unable to set the locale to "en_US.utf8". Thus, the locale keeps the default ("C"), in which case strcoll simply returns the result of strcmp. However, I need this call to run the strcoll code in order to run tests on its performance, and then tune it to run faster for specific locales.
I know that "en_US.utf8" is a valid locale for my system (Ubuntu 12.04 lts), because I see this:
$ locale -a | grep US
en_US.utf8
I have also tried running this program but setting the locale variable to other strings such as "en_US.UTF-16", "", "en_US.UTF-8", etc. all with no luck.
I imagine this isn't the first issue I will run into when trying to get locale stuff to work with my modified version of glibc, but its the first.
Any ideas On what I can do to get the locale functions (specifically setlocale) to work right?
My guess: You forgot to "make" some locales. Try:
$ make
$ make install
$ make localedata/install-locales
see also GNU libc make manual
After installation you might want to configure the timezone and locale
installation …
Try to use the strace to find out where the glibc tries to read the locales from. I suspect that since you set the prefix glibc tries to find them in ~/Desktop/bglibc/share/locale/ or something similar. And certainly UTF-16 will not work with 8 bit string types...

How do I find segmentation fault from multiple files using GDB

I have been asked in an interview how can you debug segmentation fault in C program using GDB.
I told them we can compile our program with -g option so as it add debugging information to binary file and can read core dump file but then interviewer told me if he we have 3 to 4 files compiled together but one of them causing segmentation fault then how do we debug in GDB?
$ gcc -ggdb s1.c s2.c s3.c -o myprog
$ gdb myprog
(gdb) run --arg1 --arg2
GDB will run the program as normal, when the segmentation fault occurs GDB will drop back to its prompt and it will be almost the same as running GDB with a core file. The major difference is there are some things you cannot do/print with a core file that you can when the program has crashed inside of GDB. (You can use print to call some functions inside the program, for example.)
You can also attach to an already running program using gdb --pid <the programs pid>.
Either with a core file or with one of the methods above, when you have the GDB prompt after the crash, type backtrace (or bt for short) and GDB will show you the stack at the time of the crash, including the file names and line numbers of each call and the currently executing line.
If you are working under Linux the easier way to find segmentation fault is by using the tool named VALGRIND: http://valgrind.org/ .
You just need to compile your code with -g flag and then run ./valgrind .
Then you will know exactly in which function and in which line of code there is an error-uninitialized memory/memory read out of allocated space or sth.
You just run the program under gdb, and the debugger with catch the SIGSEGV and show you the line and instruction that faulted. Then you just examine the variable and/or register values to see what's wrong. Usually it's a rogue pointer value, and trying to access it with GDB will give and error, so it's easy.
And yes, recompiling everything with -g would be helpful. The interviewer probably wanted you to describe how you'd figure out which file had the fault (gdb just tells you when it catches the signal) and just recompile that one with debug info. If there's 20,000 source files that might be useful, but with 3 or 4 files, what's the point? Even with larger projects, you usually end up chasing the bad pointer through 10 functions and 5 files anyway, so again, what's the point? Debug info doesn't cost anything at run time, although it costs disk space in an installation.
compile the code in normal way by giving gcc filename
you will get a .out file, start running that and get the process id by giving ps -aef | grep filename.out
in a another window type gdb and enter,inside gdb prompt give attach processid (processid you will get from above command),give c to continue.once the execution finishes give "bt" inside gdb.you will get the place where the segmentation is occurring.
Sounds like they are looking to set it up so that you can step through the code as it is running, you can do this with the command line version or I think you can get a GUI for GDB.
one can use the following steps to debug segmentation fault using gdb
$ gdb <exec name >
$ r //run the pgm
$ where
$ f <1> <0> //to view the function n variables
$ list
$ p <variable>

gdb and makefile

hello everyone
i try to debug a program, which have been installed by makefile.
it have a binary file of OpenDPI_demo.o and a shell shellscript OpenDPI_demo.
when i gdb OpenDPI_demo.o,i have a problem. i can't run it. the error is:
Starting program: /home/lx/ntop/test/opendpi/src/examples/OpenDPI_demo/OpenDPI_demo.o
/bin/bash: /home/lx/ntop/test/opendpi/src/examples/OpenDPI_demo/OpenDPI_demo.o:can't execute the binary file.
please tell me why. actually i can run the program by ./OpenDPI_demo.
thank you.
Based on the extension, the file is an object file. It is used by the linker (alongside other object files) to produce an executable. It's the real executable the one you want to run/debug.
This is another example of difficulties encountered with programs using libtool.
the file OpenDPI_demo alongside OpenDPI_demo.o is actually, as you said, a shell script which wraps the execution of the real compiled file, probably in .libs/OpenDPI_demo.
libtool needs this wrapper to adjust the runtime library paths and such so that you can execute the program transparently, as if it was actually installed on your system.
The way to correctly debug this application is not
/home/lx/ntop/test/opendpi $ gdb src/examples/OpenDPI_demo/.libs/OpenDPI_demo
but rather using libtool --mode=execute on the shell script, like the following (it's an example):
/home/lx/ntop/test/opendpi $ ./libtool --mode=execute gdb --args \
src/examples/OpenDPI_demo/OpenDPI_demo -f capture.pcap
Suggest you use
gdb OpenDPI_demo
instead
In your makefile if it depens on the object, make it depend on OpenDPI_demo, e.g.

Resources