the choice between whether to try to understand something by running or by reading the code is a super interesting one (though if I'm seriously interested in understanding exactly what some software does of course I'll do both!).
I think experimentation/stracing a program to understand it has a lot of advantages:
* It can be helpful to look at the system calls as a way to maybe see the big picture before diving into the code.("ok, it's setting some registers somehow, it's putting in some int3 instructions, then it does PTRACE_CONT, then it undoes all the changes it made").
* it lets me focus on what the program actually does instead of understanding how the code is organized (figuring out how the code in a large project I've never looked at before is organized can be time consuming!)
* It's easy to make incorrect conclusions when reading the source. This happens to me a lot when reading distributed systems code -- often I'll think "ok, if I do X, then Y will happen" but that turns out not to be true in practice. So I think even when you are reading code, doing experimentation as you go is a key part of making sure that your understanding of the code is actually correct.
* I find exploring programs interactively fun!
In this specific example -- I think it's really interesting that gdb modifies the `longjmp` function in libc when running a function. The string `longjmp` doesn't appear anywhere in infcall.c. So even though reading infcall.c seems like a great overview, it just has different information that I get from using strace!