gdb: No symbol "i" in current context - c

While debugging a C program in gdb I have a breakpoint in a for loop. I cannot print the value of "i" ( I get : No symbol "i" in current context.). I can print the value of all the other variables. Is it normal?
Here is the loop:
for (i=0; i < datasize; i++){
if ( feature_mask[i] > 0 ){
k = feature_mask[i] - 1;
if (neighbors[k][nmax-1] != 0){
neighbors[k][nmax-1] = bvalue;
feature_mask[i] = -feature_mask[i];
}
}
}

It has probably been optimised out of your compiled code as you only use feature_mask[i] within the loop.
Did you specify an optimization level when you called your compiler? If you were using gcc, then just omit any -O options and try again.

I encountered this issue recently. I compiled GCC 5.1 and then used it to compile a C++11 codebase. And, although I could step through the program's code in gdb, I couldn't print the value of any variable, I kept getting “No symbol "xyz" in current context” errors, for every variable.
I was using gdb 7.4, but the latest version available at the time was 7.9. I downloaded the latest version of gdb and compiled it (using GCC 5.1) and when using gdb 7.9 I was able to successfully inspect variable values again.
I guess the debug information of GCC 5.1 is incompatible with gdb 7.4.

Make sure the program is compiled without optimization, and with debugging information enabled. It's quite likely that the loop counter ends up in a register.

Check your optimization options. It's possible the GCC could replace the variable with a pointer into feature_mask.

You can try declaring i as volatile. That will prevent some compiler optimizations (and hopefully make i visible inside the debugger).

In case anyone else is using Google's Bazel build system for your project, I'd like to add that if you cannot print any variables from gdb, it may be because you need to properly add the -ggdb and -O0 (update: use -Og instead of -O0 use -O0 over -Og) C build flags using the --copt= option, INSTEAD OF using the --per_file_copt= option. In my case, although they both built and ran just fine, only the --copt= technique allowed me to fully use gdb and print variables, whereas the --per_file_copt= one also allowed me to use gdb but would NOT allow me to print variables.
Note: in the below examples, just replace test with build if you do NOT need to run the unit tests as well.
UDPATE: it turns out, you should prefer -Og over -O0 when doing debugging, so I'm updating these examples accordingly. See here: What's the difference between a compiler's `-O0` option and `-Og` option?.
So, do this:
time bazel test --copt=-ggdb --copt=-O0 \
//my/build/folder1/... //my/build/folder2/...
INSTEAD OF this:
time bazel test --per_file_copt=//my/build/folder1/...,//my/build/folder2/...#-ggdb,-O0 \
//my/build/folder1/... //my/build/folder2/...
...in order to be able to print variables from within gdb.
Again, both of the above techniques build and run just fine, and both allow me to run and use gdb, but only the first one actually allows me to use gdb to its full extent.
Lastly, if the first command above still doesn't work, try adding the --strip=never Bazel flag described here to prevent Bazel from ever stripping debugging information. Now the command will look like this:
time bazel test --copt=-ggdb --copt=-O0 --strip=never \
//my/build/folder1/... //my/build/folder2/...
Reference documentation:
--copt=:
https://docs.bazel.build/versions/master/command-line-reference.html#flag--copt
[better, with examples] https://docs.bazel.build/versions/master/user-manual.html#flag--copt
--per_file_copt:
https://docs.bazel.build/versions/master/command-line-reference.html#flag--per_file_copt
[better, with examples] https://docs.bazel.build/versions/master/user-manual.html#flag--per_file_copt
--strip=never:
https://docs.bazel.build/versions/master/user-manual.html#flag--strip
[my own Q&A] Prefer -Og over -O0 -O0 over -Og for debugging: What's the difference between a compiler's `-O0` option and `-Og` option?

Related

GDB cannot step into function, OZone can

I have a setup like this:
GDB from "GNU Arm Embedded Toolchain" 10.3-2021.10
GDB server from "Segger JLink" 7.54d
JLink Ultra+ connected to my PC and my embedded device
Arm Compiler 6.15
I'm having problems stepping into a certain function from a C module (let's call it "F1"). When trying, I get the error message
Single stepping until exit from function "F1", which has no line number information.
If I use Segger Ozone, with the same .elf file, stepping into "F1" works fine.
I've tried to narrow down the problem and have the following observations:
A single line of code from the C module holding "F1" makes the difference. If I remove this line, it works. This line is a simple incrementation (++) of a static uint32_t variable and it is in a separate function (i.e. not "F1").
If I don't link with "--inline" option, it stops working - even with the "fix" in (1)
All source files (a mix of C and C++ files) are compiled with -g option.
I may try to reproduce it in a much smaller context which I could share here but until then, I'm hoping for some hints.
Anything is appreciated.
[Update 2021-11-10] Tried with older/newer versions of "GNU Arm Embedded Toolchain" as well as "Segger JLink". Same problem.
[Update 2021-11-10] Compiler/linker command used:
armclang -g --target=arm-arm-none-eabi -mcpu=cortex-m33 -mfloat-abi=soft -MMD -Werror -D__STDC_LIMIT_MACROS -I<my_include_paths>
armlink --inline --info=sizes --info=veneers --info=unused --info=totals --map --symbols --scatter=<my_scatter_file> --list=list.txt

Issue on adding werror flag

I am trying to add warning as error flag in my makefiles. But I am getting the following problem.
When I am compiling without adding the flag it is successful. But when I am adding Werror flag in some ".mk" files, compilation is failing with some error. But in the successful build log warning was not there for that source file(".c") which is throwing error now(Werror).
I am adding he following flags.
UN_CDEFS := -Wno-error=%
CDEFS := -Wall -Werror -Wextra
SUB_CDEFS := -Wall -Werror -Wextra
So please suggest what might be the problem.
Caveat: This isn't a complete answer because we need more information, but it would become [too] lengthy for more top comments like the ones I've already posted.
As you refine the problem and/or post more data, I can edit this answer accordingly. At a minimum, posting your actual makefiles might help, as well as, the actual final cc commands and the compiler warning/error output for the failing .c file [There may be multiple ones, but the single/first one should be sufficient].
Below are some detailed instructions on how to debug this, based on my own experience with such issues.
But, before I get to that, I'll hazard a guess. I notice that you're doing:
CDEFS := -Wall -Werror
[leaving off the -Wextra as you mentioned in a comment].
If this is done as [nearly] the first thing in the makefile, it's fine. However, if it occurs in the middle, you are replacing CDEFS with your own value. If a prior line in the makefile did (e.g.):
CDEFS = -Dwont_build_cleanly_without_this_option
then, when you add your line, that could be the issue, because this gets [effectively] removed. You might try this instead:
CDEFS += -Wall -Werror
This just appends to the existing symbol, so any prior value will be retained.
Also, the base makefile might have something like:
ifndef CDEFS
CDEFS := -Dwont_build_cleanly_without_this_option
endif
Normally, make will output the full text of commands it executes to create targets. For compilation, this is (e.g.) cc -c foo.c.
Some fancier builds wrap the command in (e.g.) #doit cc -c foo.c where doit prints a message like compiling foo.c ... and only outputs the full command if there is an error. (e.g. the linux kernel build does this, IIRC). I'm assuming you don't have this, but if you do, there is usually a command line override such as make VERBOSE=1
So, there is some .c file somewhere that builds cleanly with the normal options but generates an error when extra compile options are added. Let's call this file badnews.c
What we want to see is the compilation command that make printed for badnews.c and the warning/error output for two cases:
without the extra options
with the extra options in various combinations
In particular, examining the case (1) command against the case (2) commands might show that options other than the -W are different. This indicates a makefile issue, similar to my "guess" above. You've said that [your equivalent of] case (1) is clean with no warnings, but, given the trouble you're having, it wouldn't hurt to double check.
You can cut and paste the case (1) cc command into a shell script and manually add the -W options. Watch out for things with spaces, such as -DSTRING="foo bar" in the makefile that may need extra quotes in a shell script.
To alleviate conflicts similar to yours, in my own makefiles I separate the symbols.
DFLAGS for all -DFOO=1
COPTS for -g, -O2, -Wall, -fno-inline-functions, etc.
Then, I either do:
CFLAGS := $(COPTS) $(DFLAGS)
Or:
%.o: %.c:
cc -c $(COPTS) $(DFLAGS) $<
There are other ways to do this as well.
UPDATE:
I am using following command to build: emq PRODUCT=ASG >build_log_0508.log
I'm unfamiliar with emq. I can't find a reference to it, except as "enterprise mail queue for JIRA", which [AFAICT] may be part of cPanel?
Getting the following error on compilation: prod/libs/app/app.c:720:5: error: incompatible implicit declaration of built-in function 'free' [-Werror] free(tmp_dn);
This is the smoking gun ...
I don't know what compiler you're using, or what OS/environment, but it appears to not flag this as a warning/error by default.
However, it is a bug in the source app.c that needs to be fixed. It was correctly flagged as a warning/error by the addition of -Wall and -Werror
Note: As I mentioned in my original answer, it would be helpful to have the final cc command line that produced this error [as well as the cc command when this file is not flagged].
I created a simple test case:
void
myfree(void *ptr)
{
free(ptr);
}
Here, under gcc, I did gcc -c test.c and I get:
test.c: In function 'myfree':
test.c:5:2: warning: implicit declaration of function 'free' [-Wimplicit-function-declaration]
free(ptr);
^
test.c:5:2: warning: incompatible implicit declaration of built-in function 'free'
test.c:5:2: note: include '<stdlib.h>' or provide a declaration of 'free'
So, gcc flags this by default [even without -Wall or -Werror]. But, your compiler does not unless it is given -Wall. This could occur if your compiler were clang and you also specified -std=c89
As I implied earlier, if you just specify -Wall but not -Werror, you should get the same warnings but they just won't stop the build. In a large build, they can be easily overlooked in the log [by a human (e.g.) me :-)].
Referring to the suggestions in my original answer, assuming that the cc commands between case (1) ["good"] and case (2) ["bad"] only differed by the addition of -Wall, the correct way to fix this is to edit app.c and add #include <stdlib.h> as part of the includes.
Is there any problem with "SUB_CDEFS := -Wall -Werror"?
It will have similar problems/benefits as with CDEFS.
I am adding at the end of the makefiles
This is all the more reason to use += instead of :=. You might be "killing off" the -std=c89 if that were specified somewhere.
UPDATE #2:
It worked after doing += instead of :=.
As I mentioned, using := removed some critical compile options, that were specified elsewhere in the makefile(s).
But, once again, the source code has a bug and is broken. It was broken before you ever touched it. By adding -Wall -Werror using :=, you uncovered this bug, that previously was masked incorrectly. This is a good thing.
Using += just sweeps the bug under the rug [again], by restoring some build options that were lost with :=. But, these "lost" build options were wrong. They allowed a genuine flaw in the C code to escape detection.
This is not about getting the build to work [with a workaround], but to fix the root cause of the build problems, which is to modify the C source code. There are probably other such C source code bugs and some may be more severe.
With the workaround to "fix" the build, you've now got a piece of built software that can not be trusted to run correctly. It could fail in intermittent ways on your system(s). Or, produce incorrect results. Or, allow your system to be hacked [and potentially expose you to legal liability] if you're putting this on a publicly facing site.
If you're not comfortable doing the source modification yourself, file a bug report with the original author of the software. The source code should have a README file, or BUGS file, or whatever that should outline a procedure for doing so.
Just need one more clarification for what is the difference between SUB_CDEFS, UN_CDEFS, and CDEFS
It's completely arbitrary.
Software projects built with make, can often build multiple programs or libraries. These often are placed in subdirectories. Each such subdirectory often has its own Makefile.
To avoid needless duplication [and potential error], the parts that would be common to these makefiles are placed in a single makefile, often called a rules file [but it's just a makefile]. The individual makefiles then have a line like: include ../common/rules.mk
The rules file expects that certain symbols are defined that help guide it to build the targets for the given subdirectory.
CDEFS et. al. are an example of such symbols. Names that are descriptive of function are [should be] chosen. That is, CDEFS [probably] means "C definitions". The actual symbol names and their function depends upon the rules file. We could use the symbol SHRONK instead of CDEFS. That doesn't help much with understanding things, but if all makefiles were edited to change CDEFS to SHRONK, it would work.
For example, in other software, instead of CDEFS, a similar symbol might be named CFLAGS or COPTS. This is fairly common.
Side note: It's a bit moot at this point, but things would have gone much more smoothly and quickly if you had edited your question and posted the output cc commands and [some of] your makefiles as I had requested. You would have gotten specific answers in a matter of hours instead of general guidelines [that took several days].
So, without the rules file, it's not possible to tell. Only make a guess, based upon the names:
CDEFS -- global cc options for a subdirectories
SUB_CDEF -- cc options for this particular subdirectory
UN_CDEFS -- specify -Ufoo options
The particular software you are building may have documentation for this in a documentation file or in comments in one or more of the makefiles.
To understand this generally, there are many online guides to make. Under Linux, there are "info" files. So, try info make. Other systems have detailed manpages, so do man make

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.

program variable values during execution

Is there a way to get the value of all variables in c during each execution step of a program.
Some other method except GDB.
Thanks in advance
-Sahil
The debug statements you are talking about are the printfs marcadian pointed out, which you will have to do manually, I don't know any other way in which you can tell the compiler to build the executable such that it will automatically print the variables except from GDB. All you have to do is compile the file like this : gcc -g file.c -o output.o. The -g flag constructs the table for gdb, have a look at some tutorials online http://www.cprogramming.com/gdbtutorial.html on how to use it afterwards.
Edit: info locals will be quite useful to print all the local ones

Why am I getting the message "Single-stepping until exit . . . which has no line number information" in GDB?

I've compiled my C program using gcc 4.4.1 using the flag -g, but when I try to step through one of my functions in gdb version 7.0, I get the message:
"Single stepping until exit from function _DictionaryTree_getNodeList,
which has no line number information."
Can someone tell me why this is happening?
Just guessing, but is _DictionaryTree_getNodeList in another file that wasn't compiled with -g?
I had the same problem but in my case adding -g to the compiler wasn't enough so I used -ggdb as suggested by Manav.
In my case, the problem was version skew between gcc and gdb.
After landing here from search and none of these answers fit my situation, I figured out that (because of aliases / symlinks / Makefile / environment variables) I was accidentally using a newer GCC (4.8.x) and an older GDB (7.2). Stepping up to a newer version of GDB (7.8) fixed the problem. For some reason, using a newer GCC and older GDB didn't work.
I had this error message too but the source of my problem was different. If anyone is still having any problems, make sure you have #include <stdio.h> in your file, with the the appropriate brackets around stdio.h (the text message would not show up if I had it around stdio.h).
I had the same issue, when I compiled a file using -g option and without -g option.
For one of the file, the gdb showed line number without any issues(even when it was compiled without -g option)..
And for the other file, I had to explicitly mention -g flag...
Any ideas as to whether the source file could be loaded at run time in
GDB with cross referencing would be good solution... by mapping the
lines to the addresses :D.
I had this issue because I was debugging a shared library without pointing LD_LIBRARY_PATH to correct location with debug endstates.
you can use
export LD_LIBRARY_PATH=<location of the debug build of the .so file>:$LD_LIBRARY_PATH
Hopefully this is helpful to someone
I had the same trouble despite I was already compiling with -g2. Changing it to -g3 did the trick.
Im using GBD 12 , im not able to use any of these flags and options , also im debugging .exe file , so yes I used makefile

Resources