How do I trace coreutils down to a syscall? - c

I am trying to navigate and understand whoami (and other coreutils) all the way down to the lowest level source code, just as an exercise.
My dive so far:
Where is the actual binary?
which whoami
/usr/bin/whoami
Where is it maintained?
http://www.gnu.org/software/coreutils/coreutils.html
How do I get source?
git clone git://git.sv.gnu.org/coreutils
Where is whoami source code within the repository?
# find . | grep whoami
./man/whoami.x
./man/whoami.1
./src/whoami.c
./src/whoami
./src/whoami.o
./src/.deps/src_libsinglebin_whoami_a-whoami.Po
./src/.deps/whoami.Po
relevant line (84):
uid = geteuid ();
This is approximately where my rabbit hole stops. geteuid() is mentioned in gnulib/lib/euidaccess.c, but not explicitly defined AFAICT. It's also referenced in /usr/local/unistd.h as extern but there's no heavy lifting related to grabbing a uid that I can see.
I got here by mostly grepping for geteuid within known system headers and includes as I'm having trouble backtracing its definition.
Question: How can I dive down further and explore the source code of geteuid()? What is the most efficient way to explore this codebase quickly without grepping around?
I'm on Ubuntu server 15.04 using Vim and some ctags (which hasn't been very helpful for navigating existing system headers). I'm a terrible developer and this is my method of learning, though I can't get through this roadblock.

Normally you should read the documentation for geteuid. You can either read GNU documentation, the specification from the Open Group or consult the man page.
If that doesn't help you could install the debug symbols for the c-library (it's called libc6-dbg or something similar) and download the source code for libc6) then you point out the path to the source file when you step into the library.
In this case I don't think this would take you much further, what probably happens in geteuid is that it simply issues an actual syscall and then it's into kernel space. You cannot debug that (kernel) code in the same way as you would debug a normal program.
So in your case you should better consult the documentation and read it carefully and try to figure out why geteuid doesn't return what you expect. Probably this will lead to you changing your expectation of what geteuid should return to match what's actually returned.

Related

Is there a way to get help for some C functions inside of vim/Neovim?

This question may be a little off topic. But I was wondering if there was a way for me to look at the descriptions of C functions using vim or neovim. Is it possible to look at their documentations by doing something like :help? This would really be helpful since I wouldn't need to lookup to my browser everytime.
I am unclear about these things:
Can :help be my friend here ?
Can I use LSPs to do something like this ?
I am using latest Neovim inside Ubunutu 20.04 in WSL. Is this helpful somehow ?
By pressing K, the keyword under the cursor is looked up using a configured keyword lookup program, the default being man. This works pretty much out of the box for the C standard library.
For C++, you might want to look at something like cppman.
Well yes, you can get the description of C functions by using a LSP (language server plugin)! Here is an image of me using clangd as my LSP:
You'd "just" need to install the LSP and start it. I don't know how familiar you're with neovim, but just in case if you don't know how to install a plugin or to be more specifique: If you don't know how you can install a LSP server, then you can do the following:
There're plenty videos how to set up a LSP-Server for your language. Here's an example.
If you don't want to set up on your own, you can pick up one of the preconfigured neovim setups (some of my friends are recommending lunarvim)
But yeah, that's it. If you have any further questions feel free to ask them in the comments.
Happy vimming c(^-^)c
Let's explain how "K" command works in more detail.
You can run external commands by prefixing them with :! command. So running man tool is as easy as
:!man <C-R><C-W>
Here <C-R><C-W> is a special key combination used to put word under cursor from text buffer down to command line.
Same for showing Vim's built-in help page
:help <C-R><C-W>
As it feels tedious to type that, Vim also defines K Normal mode command that does pretty much the same thing. Except the tool name is taken from value of an option named "keywordprg".
So doing set keywordprg=man (default for *nix systems) makes K to invoke !man tool; while set keywordprg=:help is for bultin help.
Also, the option :h 'keywordprg' is made global or local-to-buffer, so any Vim buffer is able to overwrite global setting. For example, this is already done by standard runtime for "vim" and "help" buffers, so they call ":help" instead of "man".
The problem with :!man command is that it shows "black console". It'd be nice if we could capture man's output and open it inside Vim just like a builtin help page. Then we could also apply some pretty highlighting, assign key macros and all such. This is a pretty common trick and it is already done by a standard plugin shipped with Vim/Neovim.
A command that the plugin provides is called :Man, so you can open :Man man instead of :!man man, for example. The plugin is preactivated in Neovim; for Vim you still need to source one file manually. So to make use of this plugin you'll need something like this
set keywordprg=:Man
if !has("nvim")
source $VIMRUNTIME/ftplugin/man.vim
endif
The previous answer recommending cppman is the way to go. There is no need to install a bulky language server just for the purpose of having the hover functionality. However, make sure you're caching the man pages via cppman -c. Otherwise, there will be a noticeable delay since cppman is fetching the page from cppreference.com on the fly.
If you like popups for displaying documentation, convert the uncompressed man pages (groff -t -e -mandoc -Tascii <man-page> | col -bx), and set keywordprg to your own wrapper to search for keywords according to your needs.

How to stop GDB stepping in to system calls? [duplicate]

I have some C++ code like this that I'm stepping through with GDB:
void foo(int num) { ... }
void main() {
Baz baz;
foo (baz.get());
}
When I'm in main(), I want to step into foo(), but I want to step over baz.get().
The GDB docs say that "the step command only enters a function if there is line number information for the function", so I'd be happy if I could remove the line number information for baz.get() from my executable. But ideally, I'd be able to tell GDB "never step into any function in the Baz class".
Does anyone know how to do this?
Starting with GDB 7.4, skip can be used.
Run info skip, or check out the manual for details: https://sourceware.org/gdb/onlinedocs/gdb/Skipping-Over-Functions-and-Files.html
Instead of choosing to "step", you can use the "until" command to usually behave in the way that you desire:
(gdb) until foo
I don't know of any way to permanently configure gdb to skip certain symbols (aside from eliding their debugging information).
Edit: actually, the GDB documentation states that you can't use until to jump to locations that aren't in the same frame. I don't think this is true, but in the event that it is, you can use advance for the same purpose:
(gdb) advance foo
Page 85 of the GDB manual defines what can be used as "location" arguments for commands that take them. Just putting "foo" will make it look for a function named foo, so as long as it can find it, you should be fine. Alternatively you're stuck typing things like the filename:linenum for foo, in which case you might just be better off setting a breakpoint on foo and using continue to advance to it.
(I think this might be better suited as a comment rather than an answer, but I don't have enough reputation to add a comment yet.)
So I've also been wanting to ignore STL, Boost, et al (collectively '3rd Party') files when debugging for a while. Yesterday I finally decided to look for a solution and it seems the nearest capability is the 'skip' command in GDB.
I found the 'skip' ability in GDB to be helpful, but it's still a nuisance for me because my program uses a lot of STL and other "3rd Party" template code. In this case I have to mark a bunch of files as skip. After the 2nd time doing so I realized it would be more helpful to be able to skip an entire directory--and most helpful to skip a directory and all subdirectories. That way I can skip, for example, /usr since none of my code lives there and I typically have no interest in debugging through 3rd party code. So I extended the 'skip' command in gdb to support a new type 'dir'. I can now do this in gdb:
skip dir /usr
and then I'm never stopped in any of my 3rd party headers.
Here's a webpage w/ this info + the patch if it helps anyone: info & patch to skip directories in GDB
It appears that this isn't possible in GDB. I've filed a bug.
Meanwhile, gdb has the skip function command. Just execute it when you are inside the uninteresting function and it will not bother you again.
skip file is also very useful to get rid of the STL internals.
As Justin has said, it has been added in gdb 7.4. For more details, take a look at the documentation.

How do I check /etc/network/interfaces file grammar and test it in C code?

I have a file ("interfaces_new" like /etc/network/interfaces) that I have to test.
Tests concerns File grammar and if I can detect if the settings are correct by testing, it is only better.
I searched and I fell on the ifup command that seems to do everything I want.
The trouble is that I do not want to call system in my C code, so I try to retrieve the sources of ifupdown.
I do not even succeeded, many result indicating to me that a script ifup on most system. On my Debian 7.1.0, it is a EFL binary.
What comes to my questions:
* Is it a usable tool in C code which allows to parse the grammar of a file / etc / network / interfaces?
* Is there a doc listing all the valid options? ifup man gives nothing (or I look bad :/ ), the idea being to make my own parser.
* How to get the source code of the ifup command to Debian 7.1.0?
As I originally commented:
You should read and learn more about parsing. Read interfaces(5) to understand the format of /etc/network/interfaces
The ifup command is from ifupdown package, so get its source code.
At last, you simply could popen(3) the following command
ifup --verbose --no-act --force --all --interfaces=/tmp/interfaces_new
assuming your file is in /tmp/interfaces_new.
(Warning, I did not test my suggestion, leaving that to you)

How to find the callers and callee of a function in C code in vi/vim?

I want to know how can I easily click (or maybe use some easy shortcuts) on a function name and find all its callee or open where it has been defined. Most of the web manuals in web are really hard to follow or don't happen to work out. Say I want to click on allocuvm and see where it has been defined?
uint newstk=allocuvm(pgdir, USERTOP-PGSIZE, USERTOP);
cscope minimal example
Ingo mentioned it, here is an example.
First you should set on your .vimrc:
set cscopequickfix=s-,c-,d-,i-,t-,e-
Then to the base directory of your project and run:
cscope -Rb
This generates a cscope.out file which contains the parsed information. Generation is reasonably fast, even for huge projects like the Linux kernel.
Open vim and run:
:cs add cscope.out
:cs find c my_func
c is a mnemonic for callers. The other cscope provided queries are also possible, mnemonics are listed under:
help cscope
This adds a list of the callers to the quickfix list, which you can open with:
:copen
Go to the line that interests you and hit enter to jump there.
To find callers of the function name currently under the cursor, add to your .vimrc:
function! Csc()
cscope find c <cword>
copen
endfunction
command! Csc call Csc()
and enter :Csc<enter> when the cursor is on top of the function.
TODO:
do it for the current function under cursor with a single command. Related: Show function name in status line
automatically add the nearest database (parent directories) when you enter a file: how to auto load cscope.out in vim
interactively open the call graph like Eclipse. Related: Generate Call-Tree from cscope database
A word of advice: I love vim, but it is too complicated for me to setup this kind of thing. And it does not take into account classes e.g. in C++. If a project matters enough to you, try to get the project working on some "IDE". It may involve some overhead if the project does not track the IDE configuration files (which are auto-changing blobs that pollute the repo...), but it is worth it to me. For C / C++, my favorite so far was KDevelop 4.
For that, Vim integrates with the cscope tool; see :help cscope for more information.
vi / . --- / is the search function in vi, and . will repeat the same command.
you could also use sed ( stream editor ) if it is a large file
sed
grep can get you the line numbers
read the man page

gprof : How to generate call graph for functions in shared library that is linked to main program

I am working on Linux environment. I have two 'C' source packages train and test_train.
train package when compiled generates libtrain.so
test_train links to libtrain.so and generates executable train-test
Now I want to generate a call graph using gprof which shows calling sequence of functions in main program as well as those inside libtrain.so
I am compiling and linking both packages with -pg option and debugging level is o0.
After I do ./train-test , gmon.out is generated. Then I do:
$ gprof -q ./train-test gmon.out
Here, output shows call graph of functions in train-test but not in libtrain.so
What could be the problem ?
gprof won't work, you need to use sprof instead. I found these links helpful:
How to use sprof?
http://greg-n-blog.blogspot.com/2010/01/profiling-shared-library-on-linux-using.html
Summary from the 2nd link:
Compile your shared library (libmylib.so) in debug (-g) mode. No -pg.
export LD_PROFILE_OUTPUT=`pwd`
export LD_PROFILE=libmylib.so
rm -f $LD_PROFILE.profile
execute your program that loads libmylib.so
sprof PATH-TO-LIB/$LD_PROFILE $LD_PROFILE.profile -p >log
See the log.
I found that in step 2, it needs to be an existing directory -- otherwise you get a helpful warning. And in step 3, you might need to specify the library as libmylib.so.X (maybe even .X.Y, not sure) -- otherwise you get no warning whatsoever.
I'm loading my library from Python and didn't have any luck with sprof. Instead, I used oprofile, which was in the Fedora repositories, at least:
operf --callgraph /path/to/mybinary
Wait for your application to finish or do Ctl-c to stop profiling. Now let's generate a profile summary:
opreport --callgraph --symbols
See the documentation to interpret it. It's kind of a mess. In the generated report, each symbol is listed in a block of its own. The block's main symbol is the one that's not indented. The items above it are functions that call that function, and the ones below it are the things that get called by it. The percentages in the below section are the relative amount of time it spent in those callees.
If you're not on Linux (like me on Solaris) you simply out of luck as there is no sprof there.
If you have the sources of your library you can solve your problem by linking a static library and making your profiling binary with that one instead.
Another way I manage to trace calls to shared libraries, is by using truss. With the option -u [!]lib,...:[:][!]func, ... one can get a good picture of the call history of a run. It's not completely the same as profiling but can be very usefull in some scenarios.

Resources