title: How to get full path to source file in C?
body: <p>I know that I can do the following to print the source file from within a C program:</p>
  
  <pre><code>printf("__FILE__: %s\n", __FILE__);
  </code></pre>
  
  <p>However, this yields the "path by which the preprocessor opened the file", according to the <a href="https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html" rel="nofollow noreferrer">docs</a>. In this case it gives:</p>
  
  <pre><code>__FILE__: common.c
  </code></pre>
  
  <p>I know further that I can use the following <a href="https://releases.llvm.org/7.0.1/tools/clang/docs/SanitizerCoverage.html" rel="nofollow noreferrer">clang feature</a> to print the source file as well:</p>
  
  <pre><code>void *pc = __builtin_return_address(0);
  char pc_desc[1024];
  __sanitizer_symbolize_pc(pc, "%p %F %L", pc_desc, sizeof(pc_desc));
  printf("__sanitizer_symbolize_pc: %s\n", pc_desc);
  </code></pre>
  
  <p>Similarly, though, it only prints the relative path:</p>
  
  <pre><code>__sanitizer_symbolize_pc: 0x10563a873 in Y common.c:4
  </code></pre>
  
  <p>This is a problem when two files have the same static function (in this case <code>Y</code>) on the same line in separate sub-directories, e.g.:</p>
  
  <pre><code>__sanitizer_symbolize_pc: 0x10563a873 in Y common.c:4
  __sanitizer_symbolize_pc: 0x10563a933 in Y common.c:4
  </code></pre>
  
  <p>Of course the code could be refactored, or the binary matched to the source code after the program runs, or the compilation process could be changed to compile the <code>common.c</code> file from a higher-up parent folder. But given this example, how does one get the full path to the source file from the C program itself?</p>
  
  <p>It seems that clang's IR has the directory info preserved <a href="http://llvm.org/doxygen/classllvm_1_1DIScope.html#aa15b555d1f611dd569d76097fd969da1" rel="nofollow noreferrer">in metadata</a>, but it is unclear how it is accessed. For example, the <code>common.ll</code> file contains the following line:</p>
  
  <pre><code>!1 = !DIFile(filename: "common.c", directory: "/full/path/to/subdir")
  </code></pre>
  
  <p><sub>
  I am using manually-compiled clang 7.0.1 on Mac OS.
  </sub></p>