Show macros in debug symbols (embedded) - c

I am working with embedded application, and during debugging, the debugger is not able to resolve macro symbols (my theory: because macros are lost in preprocessing). I end up having to find the macro in source code first and then use the definition to watch a variable.
My question is:
Is there a way to incorporate the macro definition inside by elf file?
If yes, what steps do I need (flag do i need to set during compile, for example)?
If no, why not?
Any info is appreciated.
My exact setup is WindRiver compiler and lauterbach debugger.
But if you have info about other environment, please share, perhaps I can find a counterpart for my environment.

Not sure how this translates to your compiler & debugger, but it's possible with GCC and GDB.
If you rebuild and tell GCC to generate debug symbols optimized for GDB, using -ggdb3, it can preserve macro information:
$ make KCFLAGS=-ggdb3
...
(gdb) info macro task_is_stopped_or_traced
Defined at include/linux/sched.h:218
included at include/linux/nmi.h:7
included at kernel/sched.c:31
#define task_is_stopped_or_traced(task) ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
(gdb) macro expand task_is_stopped_or_traced(init_task)
expands to: ((init_task->state & (4 | 8)) != 0)
(gdb) p task_is_stopped_or_traced(init_task)
$2 = 0

Usually, macros do not appear in debugging symbols because of how C files are compiled.
First, the file is preprocessed, and macros are expanded. Then, all preprocessing directives are deleted, and macro definitions discarded. Next, the actual compiling to machine code takes place, and this is where the compiler builds debugging information.

Related

gdb get preprocessor macro info from file in different directory

I'm trying to debug some additions I made to a fairly large c program using gdb. The program I'm trying to debug makes extensive use of #define statements to set different values that are used throughout the code. I need to be able to see what these values are in order to help my debugging (as they include some very important information.
After some digging around I found that the info macro FOO and macro expand FOO commands should be able to print these values if the -g3 option (also tried the -gdwarf-2 and -ggdb3 flags as well) is passed to the compiler (as discussed here). However, whenever I try using this I get
The symbol `FOO' has no definition as a C/C++ preprocessor macro
at <user-defined>:-1
Now, I'm sure that the macro is defined otherwise the previous line of code would not have been able to run. In addition, I'm certain that I have passed the -g3 flag to the compiler. I have one idea as to where the issue might be and that is the location that the macro is defined at. Currently the macro is defined in a header file that is not in the same directory as the rest of the files (i.e. if the source files are in /foo/bar/blam/.. then the macro is defined in /def/mac/here/. Given this I thought maybe the problem was that gdb didn't know to look in this directory so I tried issuing the directory command in gdb and gave it the path to the directory containing the header file (base on this). This still did not solve the problem.
Does anyone know how I can get the values of these macros? If it is pertinent I'm running gdb version 7.11 and compiling the program using
cc and gcc both with Apple LLVM version 7.0.2 (clang-700.1.81). Also, gdb was installed/built using homebrew.

CLion fails to index C preprocessor macros when -std=gnuXX is set (Linux Kernel Headers)

I am trying to write a Linux kernel module with CLion. This is the cmake file:
cmake_minimum_required(VERSION 3.5)
project(labs)
set(KERNEL_HEADERS
/home/alex/Developer/linux/include
/home/alex/Developer/linux/arch/x86/include
/home/alex/Developer/linux/arch/x86/include/generated
/home/alex/Developer/linux/include/uapi
/home/alex/Developer/linux/include/generated/uapi
/home/alex/Developer/linux/arch/x86/include/uapi
/home/alex/Developer/linux/arch/x86/include/generated/uapi
)
set(MY_MODULE_SOURCES
chapter_03/lab_01/hello.c
)
add_definitions(-imacros /home/alex/Developer/linux/include/linux/kconfig.h)
add_definitions(-D__KERNEL__)
add_definitions(-DMODULE)
add_definitions(-std=gnu89)
include_directories(${KERNEL_HEADERS})
add_custom_target(labs COMMAND $(MAKE) -C ${labs_SOURCE_DIR}
PWD=${labs_SOURCE_DIR})
add_library(dummylib ${MY_MODULE_SOURCES})
The actual building of the kernel module is done with the externally called makefile using "add_custom_target". The "dummylib" is only there so that CLion actually starts to parse the header files and gives me auto completion. With my supplied definitions it does even compile the "dummylib" successfully (look at the screenshot). It is no kernel module though, but that does not matter ;)
My problem is the error you see in the screenshot. Somehow it says that it can't resolve all the macros defined in the kernel headers. Functions, structs and plain defines ( "MODULE_SIG_STRING ") do work (as you see). I do not understand why the editor says it cannot resolve the macro but can still build it. What is more strange is that I can even jump to the declaration using STRG+B of the marked macros. Clearly something is going wrong. The macros are really defined within linux/module.h.
Update
When I set -std=c89 instead of -std=gnu89 the editor recognizes the macros but the "dummylib" of course fails to build since the kernel needs the gnu extensions. I guess this is a bug in CLion. I posted it at the Jetbrains Bugtracker: https://youtrack.jetbrains.com/issue/CPP-6875

Pro*C based batch, Out of Memory?

When trying to compile a Pro*C based batch file, the process "proc" stucks at 100% of 1 CPU core and the memory starts growing to a point where the system needs to OOM kill the process (the machine has 16GB Memory and the process grew up to 9GB).
Has anyone seen this behavior before?
As an aditional information:
-The mk is the one from the instalation of the main package
-The .pc files are the original files (I've tried to compile several, such as dtesys.pc)
-The Libs are correctly compiled
-The environment variables are correctly set
Yes, it is limits.h because it includes itself recursively on line 123:
/* Get the compiler's limits.h, which defines almost all the ISO constants.
We put this #include_next outside the double inclusion check because
it should be possible to include this file more than once and still get
the definitions from gcc's header. */
#if defined __GNUC__ && !defined _GCC_LIMITS_H_
/* `_GCC_LIMITS_H_' is what GCC's file defines. */
# include_next <limits.h>
#endif
So, the solution is to pass parse=none option to Pro*C precompiler:
proc parse=none iname=filename.pc oname=filename.c
Or, a second option: you may first precompile your source with c precompiler to get pc file:
cpp -P -E yourfile.someextension -o yourfile.pc
Then you will get limits.h parsed without recursion.
-P option is needed because Pro*C is the program which can be confused with linemarkers.
-E option is needed because Pro*C is the program which can be confused with non-traditional output.

Including header files in C

I am working on a project in which If I could include a header file at runtime, it would save some programming effort. I google'd about it, but all in vain. My question is :
Can we include header files in a C program at runtime ?
If yes, how?
If not, why?
In C the source files are only read compile-time, so the answer to your question is not. Runtime there is only the executable binary, which has nothing to do with your source code headers.
Not really, no. Header files are brought in by the compiler to satisfy symbols needed during compilation.
If you simply want values unrelated to compilation, you can always put them in a configuration file which is read at runtime.
Other possible solutions are command line arguments or environment variables but, since you're discussing putting them into a file, the first option is probably the best.
No header files can't be added at run-time as,
The four stages for a C program to become an executable are the following:
1) Pre-processing
2) Compilation
3) Assembly
4) Linking
and Pre-processing is the very first stage through which a source code passes. In this stage the following tasks are done:
1) Macro substitution
2) Comments are stripped off
3) **Expansion of the included files**
and observation from intermediate file shows that we can get by passing argument to gcc as gcc -Wall -save-temps hello.c -o hello :
1) All the macros are expanded in the preprocessing stage.
2) All the comments are stripped off.
3) The third observation is that beside the line ‘#include’ is missing and instead of that we see whole lot of code in its place. So its safe to conclude that stdio.h and header files has been expanded and literally included in our source file.
and then compilation of code takes place ..
So including header files before compilation is needed.

Why are some debug symbols missing and how to track them?

I am currently debugging a Kernel module and to this purpose, I built the whole kernel with debug information (produces kallsyms, etc ...).
When I try nm my_module.ko, I get the list of symbols included by my module. All is allright except that some symbols are kind of missing as they do not appear in the symbol list. My feeling about this is that the related functions are being automatically inlined.
Anyway, when running the kernel with qemu-kgdb/gdb, I am able to see that the "missing" function is called. This means the compiler did not wipe it out because it was never used in any code path (hence my "feeling").
Since the symbol does not appear, I can't set a breakpoint on it and gdb won't unroll it so that I can see the running code path - understand I don't know how to tell gdb to unroll it.
Unfortunately, I want to see this part of the code path ... How can I do so ?
EDIT : As suggested in Tom's answer, I tried using the file:line syntax as below :
My code file looks like this :
int foo(int arg) // The function that I suspect to be inlined - here is line 1
{
/* Blabla */
return 42;
}
void foo2(void)
{
foo(0); // Line 9
}
I tried b file.c:1, and the breakpoint was hit but the foo() function is not unrolled.
Of course, I am producing debug symbols, since I also set a breakpoint to foo2 to check what happened (which worked well).
You don't say what version of gdb you are using.
Very old versions of gdb don't have any support for inline functions. This was true for 6.8 and maybe even 7.0 -- I don't recall. You can look at the NEWS file for your gdb to see.
Then there were some versions of gdb that supported breakpoints on inline functions, but only using the "file:line" syntax. So what you would do is look up the function in your editor, and find its line number and enter, e.g.:
(gdb) break myfile.c:777
Even more recent versions of gdb, starting with 7.4 or 7.5 (I forget) will handle "break function" just fine if "function" was inlined.
All of this only works if you have debuginfo available. So if you tried this, and it failed, either you have an older gdb, or you forgot to use -g.
There's no good way inside gdb to see what objects in a compilation were missing -g. You can see it pretty easily from the shell, though, by running "readelf -WS" on the .o files, and looking for files that don't have a .debug_info section.
Setting a breakpoint to the signature line of the function did not work. But setting one to the line of an instruction of the inlined function solved the problem for me. For instance, considering the following function inline_foo, found in myfile.c:
inline int inline_foo(int arg) // l.1
{
int a_var = 0;
do_smth(&a_var);
do_some_other_thing(); // l.5
if (a_var) {
a_var = blob();
} else {
a_var = blub();
return a_var; // l.10
}
I was trying b myfile.c:1, which did not appear to work. But if I tried b myfile.c:3 instead, the breakpoint was well handled by GDB.
Since the technique is the same as the one described previously by Tom, I'll accept his answer.

Resources