>I'm probably missing your point, since one certainly don't need a preprocessor for line numbers in logging statements.
So, libc doesn't define anything like pclntab. About the closest you can really get is DWARF2 call frame information, which is generally treated as debug information (because, well, it _is_) and stripped in release builds. Further, not all platforms will use DWARF2, and the way it is embedded in binaries differs.
(Example: In Win32, when you are using MinGW, DWARF2 will be embedded as PE sections, which have 8 character long names; this is not long enough for the DWARF section names, so a special PE extension is used to specify the longer section names.)
What i'm trying to illustrate is, it's really, truly not possible to go from a PC value, to a line number in a source file, in pure C, at runtime. However, of course, as you have no doubt noticed, everyone still manages to print out line numbers in C source code. And they do this using the preprocessor.
If you dig deep enough into pretty much any logging library that offers line numbers in C and C++, you will find a macro that passes through __FILE__ and __LINE__. And if you keep tracing, you will probably also find the 'function' you call to log is a macro that eventually calls this macro. As a quick example, here is one in glog, a logging library used at Google:
https://github.com/google/glog/blob/41f4bf9cbc3e8995d628b459...
Pantheios is another popular logging library, and it defines macros that can be used to control the prefix.
https://github.com/synesissoftware/Pantheios/blob/177dc5fcff...
If you look into your logging library, it is quite likely that you will find that at the end of the day, it boils down to the __FILE__ and __LINE__ macros. When all of the macros are computed for your log line, the preprocessor subs in a string literal and line number for the filename and the line number that the macro was originally invoked from.