A particularly large (~10^6 LOC) program causes my stty settings to change from echo ixon icanon
to -echo -ixon -icanon
and I would like to find the function in this massive program that causes this change.
I obviously would not like to trace execution through this mess of OOP spaghetti code.
How can I monitor stty settings and log what changes them? I'm thinking strace
with awk
can probably get me the info I need, but I don't know what system calls to filter for.
Best Answer
If you think that you can cause the event by a specific action or interaction, by far the simplest method is something like:
Run this on a new terminal, the option to
-F
is the terminal you will run the program on (runtty
to see what it is before starting it). Omit| grep ..
if you want to observe the complete terminal state.Next option, if you are using Linux, is to use
ltrace
to trace library calls, this similar tostrace
(and it incorporates somestrace
capability) but it works with user-space libraries, not just the kernel system calls:This will show and timestamp calls to
tcgetattr()
andtcsetattr()
, the libc functions to get and set terminal attributes.Ultimately, those libc calls will use the
ioctl()
system call, this you can trace withstrace
ortruss
, here's how to usestrace
on linux:A big advantage here is that
strace
will happily decode various parameters to syscalls for you.None of the above will tell you very much about logically where in the program the problem might occur though, to do that you have two options: a debugger, or DLL injection.
Within
gdb
you can easily set a breakpoint ontcsetattr()
, then check the call stack, but this may be tedious if there are many calls (and will require a debug build or symbols for libc to get the best results).The most comprehensive option (assuming that the target program is dynamically linked) is to inject your own DLL which intercepts or wraps the functions you need to track, in this case
tcsetattr()
.Compile and invoke as indicated in the comments. This code locates the real libc
tcsetattr()
function, and contains an alternative version which is used instead. This code callsbacktrace()
when it sees possibly interesting activity on FD 0, then calls the real libc version. It may require minor adjustment.