Reputation: 855
I know that I can do the following to print the source file from within a C program:
printf("__FILE__: %s\n", __FILE__);
However, this yields the "path by which the preprocessor opened the file", according to the docs. In this case it gives:
__FILE__: common.c
I know further that I can use the following clang feature to print the source file as well:
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);
Similarly, though, it only prints the relative path:
__sanitizer_symbolize_pc: 0x10563a873 in Y common.c:4
This is a problem when two files have the same static function (in this case Y
) on the same line in separate sub-directories, e.g.:
__sanitizer_symbolize_pc: 0x10563a873 in Y common.c:4
__sanitizer_symbolize_pc: 0x10563a933 in Y common.c:4
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 common.c
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?
It seems that clang's IR has the directory info preserved in metadata, but it is unclear how it is accessed. For example, the common.ll
file contains the following line:
!1 = !DIFile(filename: "common.c", directory: "/full/path/to/subdir")
I am using manually-compiled clang 7.0.1 on Mac OS.
Upvotes: 0
Views: 3316
Reputation: 914
can consider giving it a full path at compile time?
like the following, call the realpath
to take a full path
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
CFLAGS = -g -Wall
CC = clang
BIN = test
$(BIN) : $(OBJS)
$(CC) $^ -o $@
%.o : %.c
$(CC) $(CFLAGS) -c $(realpath $<)
clean:
rm -f $(OBJS) $(BIN)
Upvotes: 2