1

I see a string being output to my Terminal, when I ran an executable. I have the source code (in C) of the executable, but it was not written by me. I compiled it with -g flag. Is there any way to know which line in which file resulted in the output, with dtrace, lldb, gdb, or any other means?

I am using macOS 10.13. When I ran gdb and the following: catch syscall write

I got this error: The feature 'catch syscall' is not supported on this architecture yet.

Is there any way that can achieve my goal?

ks1322
  • 33,961
  • 14
  • 109
  • 164
forgodsakehold
  • 870
  • 10
  • 26

1 Answers1

0

lldb tends to be better supported on macOS than gdb. You should be able to trace this call by using its conditional breakpoint feature.

While you can certainly trace the write() call with dtrace and get a stack trace using the ustack() action, I think you'll have a harder time pinpointing the state of the program than if you break on it in the debugger.

Your comment suggests you might be searching for a substring match. I suspect you can create a conditional breakpoint in lldb that matches a substring using something like this:

br s -n write -c 'strnstr((const char*)$rsi, "test", $rdx) != NULL'

I'm assuming lldb does not have argument names for the write function, so I'm using x86-64 calling convention register names directly. ($rdi = first argument, which would be the file descriptor; $rsi = second argument, buffer; $rdx = third argument, buffer length)

pmdj
  • 22,018
  • 3
  • 52
  • 103
  • Thank you for your answer @pmdj. But can you give more details on how to use conditional breakpoint to trace the syscall write? The link to another Stack Overflow question only talks about using string equality as a condition... – forgodsakehold Aug 10 '20 at 05:12
  • @forgodsakehold Your question does not specify what you're looking for - "I see a string being output" suggested to me this was a fixed string. – pmdj Aug 10 '20 at 12:26
  • I've updated the answer to show an example of how I'd implement a conditional breakpoint on write() where the written string contains a substring "test" - perhaps that's what you were after. – pmdj Aug 10 '20 at 12:35
  • 1
    Note, lldb supports `$arg` as aliases for the GPR argument passing registers in the current ABI. So you can do this with `$rdi` -> `$arg1`, etc... – Jim Ingham Aug 10 '20 at 18:08
  • @JimIngham I did not know that, that's a super handy tip, thank you! – pmdj Aug 11 '20 at 09:36