Linux gdb 'examine' behavior - c++

I'm using gdb to explore a core file on Linux and I noticed weird behavior when examining memory addresses:
(gdb) x/f 0xbd091a10
0xbd091a10: 0
(gdb) x/g 0xbd091a10
0xbd091a10: 65574
(gdb) x/f 0xbd091a10
0xbd091a10: 65574
These statements were run directly back to back, and I don't understand why examining as float returns inconsistent results. The value 65574 does make sense as it corresponds to the identity of the last loaded item by the process.
Does anyone know the reason for this?
Version details:
Linux mx534vm 2.6.18-308.el5 #1 SMP Fri Jan 27 17:17:51 EST 2012 x86_64 x86_64 x86_64 GNU/Linux
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-32.el5)

There is no inconsistency in this. 'f' and 'g' are specifiers in different categories, 'f' for format and 'g' for unit size. Each specifier, when used, becomes the default for its own category which holds for all subsequent uses of 'x'. Thus, your two last commands are both equivalent to x/fg 0xbd091a10.

Related

How to determine why a C program outputs unexpected messages?

I'm trying to program in C on Eclipse, I have installed and configured MinGW, but I have a problem that I don't understand:
I have some simple code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int num1,num2;
setbuf(stdout,NULL);
printf("enter two numbers");
scanf("%d%d",&num1,&num2);
if(num1>num2){
printf("num1 is greater than num2");
}else{
printf("num2 is greater than num1);
}
return 0;
}
After I compile and run, it shows me "Enter two numbers" and I enter two numbers, I can't see any further output and keyboard function doesn't work on console screen, it doesn't give me an error, but it does show some strange output on console:
<terminated>
<terminated>(exit value: -1.073.741.515) CPS:exe
You're not reading in the values correctly:
scanf("%d%d",num1,num2);
The %d format specifier for scanf expect a int *, i.e. a pointer to an int, as an argument. It needs the address of a variable to be able to write a value to where that address is stored.
You're instead passing the current values of num1 and num2 which are essentially garbage values because the variables have not been written to.
You instead want:
scanf("%d%d",&num1,&num2);
I don't kwon if the code you post is exactly the same as what you compiled, when I copy and compile the code you posted, gcc report an error at line:
printf("num2 is greater than num1);
There lost the ending quotation mark in printf();
After I fixed this error, it works well. My environment is
Linux DESKTOP-7VH0PN1 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
With gcc:
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.

Get system information with Fortran

I'm interested in getting system information through Fortran - categories may include:
Operating system name
Operating system version
CPU architecture (32/64-bit)
Number of cores
It's my understanding that you can get basic OS information through preprocessing directives, such as
#ifdef _WIN32
print *,'Windows'
#ifdef _APPLE_
print *,'macOS'
#ifdef __linux
print *,'Linux'
#endif
This is a working solution for category 1, but still leaves 2 - 4.
Thanks!
You can kinda do all that stuff in Fortran, except not really. The COMPILER_VERSION() string from the ISO_FORTRAN_ENV module should provide the name of the OS at least. From that you know what procedures to invoke to get further information.
program test
use ISO_C_BINDING
use ISO_FORTRAN_ENV
implicit none
integer, parameter :: bitness = bit_size(0_C_INTPTR_T)
write(*,'(*(g0))') 'This is a ',bitness,'-bit system.'
write(*,'(*(g0))') COMPILER_VERSION()
end program test
Here's my output with gfortran:
This is a 64-bit system.
GCC version 7.2.0
So gfortran isn't very helpful. I consider that to be a bug. ifort doesn't have COMPILER_VERSION() at all; maybe that's just because I have old versions of both compilers. Anyway, if you could get the OS from the COMPILER_VERSION() string, you would know how to load useful functions like LoadLibrary and GetProcAddress in Windows. Then you create parameters that have the names of the OS procedures you want if you have the right OS and the name of a stub procedure if not.
logical, parameter :: v0 = index(v5,'WINDOWS') /= 0
character(*), parameter :: v6 = merge('LoadLibraryA','Stub12345678',v0)
interface
function LoadLibrary(lpFileName) bind(C,name=v6)
import
implicit none
!DEC$ ATTRIBUTES STDCALL :: LoadLibrary
!GCC$ ATTRIBUTES STDCALL :: LoadLibrary
integer(C_INTPTR_T) LoadLibrary
character(kind=C_CHAR) lpFileName(*)
end function LoadLibrary
end interface
That way you can access LoadLibrary if you're in Windows and not cause an unsatisfied external reference if not. Unfortunately gfortran doesn't think having a named constant rather than a character literal for the binding name is valid.
But in principle you can use the compiler to tell you the OS name and set up a few critical functions you need to beg the OS for the rest of the stuff, but it needs a more advanced compiler than I've got. If you have a better compiler I could edit in more stuff and you could see if it crashes on your end.
Once you finished point 1 in the way you showed in the question you can go on for the other points.
In POSIX systems (including Linux) you can execute
uname -a
to get the OS name and version information like
Linux meop37 4.4.104-18.44-default #1 SMP Thu Jan 4 08:07:55 UTC 2018 (05a9de6) x86_64 x86_64 x86_64 GNU/Linux
you can store this in a file and read the file Fortran (just redirect stdout).
In Linux you can read /etc/os-release to find out the OS version.
In my case it includes:
NAME="openSUSE Leap"
VERSION="42.2"
ID=opensuse
...
In Linux you can read /proc/cpuinfo to get a lot information about the CPU (including those you request). It is your responsibility to parse it somehow in Fortran.
In my case it contains:
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i7-3770 CPU # 3.40GHz
stepping : 9
microcode : 0x1c
cpu MHz : 1693.800
cache size : 8192 KB
physical id : 0
siblings : 8
core id : 0
cpu cores : 4
...
I have zero knowledge about MS Windows. Your question is very (too?) broad so I think answering just a part of it is acceptable.
I give answer for architecture and detail system information in Windows 10. (maybe it can work in other Windows systems.)
program info
implicit none
print*,'detail system information: (on Windows 10)'
call system('SystemInfo')
print*
read(*,*)
print*,'system architecture:'
call system('wmic OS get OSArchitecture')
print*
end program
I used help from to obtain architecture. Generally subroutine call system(String_variable) starts up cmd line and get system commands. Similar way it starts up terminal in Ubuntu and get shell commands. (System commands are obviously different for different operation systems.)

GDB not seeing correct function argument values even though they are set

First time trying to debug on a quad-core Xeon after 15 years of successful x86 GDB use.
Linux DellT3500 3.16.0-23-generic #31-Ubuntu SMP Tue Oct 21 17:56:17 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
GNU gdb (Ubuntu 7.8-1ubuntu4) 7.8.0.20141001-cvs
g++ compiler flags:
-Wall -Wwrite-strings -Wchar-subscripts -Wparentheses -gstabs+ -DLINUX -O0
Setting a breakpoint in a certain class member function shows this=0x0 and the other parameter incorrectly when the breakpoint happens. But inserting a printf in the code right after that shows that this and the parameter are actually set correctly:
Breakpoint 1, PlayGamePage::actionPerformed (this=0x0, inTarget=0x7fffffffdf90)
at PlayGamePage.cpp:725
725 printf( "hey, this = %x, inTarget = %x\n", this );
(gdb) next
hey, this = b6cc50, inTarget = b6ce18
727 if( inTarget == &mCommitButton &&
(gdb) print this
$1 = (PlayGamePage * const) 0x0
(gdb) print inTarget
$2 = (GUIComponent *) 0x7fffffffdf90
(gdb)
But you can see how GDB can't even print these values correctly, even though they are set and printable by the code with printf. This is is a big problem, because GDB has no access to printing member variables.
Also, the rest of the function body uses this extensively and inTarget extensively (accessing class members and testing inTarget), and the code functions as expected. No crashes or misbehavior, so this is set correctly in the code, but GDB can't see it.
Going up the stack:
(gdb) up
#1 0x000000000040a11f in ActionListenerList::fireActionPerformed (
this=0xb6cf98, inTarget=0xb6cf48)
at ../../minorGems/ui/event/ActionListenerList.h:134
134 listener->actionPerformed( inTarget );
See that inTarget matches what printf sees down in the actionPerformed function body. Also, gdb can print these values fine at this point:
(gdb) print inTarget
$5 = (GUIComponent *) 0xb6cf48
(gdb) print listener
$6 = (ActionListener *) 0xb6ce18
listener should match this down in the function body, and it does according to printf, but gdb sees this=0x0 instead.
Yes, this is a virtual function that is being called (PlayGamePage implements the ActionListener interface, overriding the actionPerformed virtual function).
I just placed a breakpoint in exactly the same code in GDB on 32-bit x86, and it sees both this and inTarget correctly and can print them correctly, with values matching what the code's printf shows.
This is either a bug in your GCC (which version are you using?) or a bug in GDB.
Since you are apparently running an old CVS snapshot of GDB, I suggest first trying a stable GDB release instead.

gdb: print doesn't recognize variables with non-standard names or characters?

I'm writing a little BASIC compiler using LLVM, everything works fine. I'm trying to get debugging to work, and it's going fine, but I have a weird issue with variable names and GDB's print statement.
A little background on BASIC for those not familiar:
In BASIC, variable names use a symbol on the end to determine their type. So a variable x% would be integer, and variable x$ would be a string, and both can co-exist.
The statement DEFINT A-Z means that any variable starting with any letter from A to Z will be type INT, even without the trailing %. But, internally, my compiler will store the name mangled with the trailing % to avoid overlap with another variable with a trailing $.
Here is my little test program:
defint a-z
x = 5
y = 100
z = x + y
if x = 5 then
print "z=";z
else
print "z!=";z
end if
So 'x' is actually stored internally and put into the symbol table as x%.
OK, so I load my compiled EXE into GDB...
D:\dev\BasicParser>gdb t.exe
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-mingw32".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from D:\dev\BasicParser\t.exe...done.
(gdb) b _jbc_main
Breakpoint 1 at 0x401000: file t.bas, line 1.
(gdb) r
Starting program: D:\dev\BasicParser\t.exe
[New Thread 1532.0x25b8]
Breakpoint 1, _jbc_main () at t.bas:1
1 defint a-z
(gdb) n
4 x = 5
(gdb) info address x%
Symbol "x%" is static storage at address 0x4263c4.
At this point, you can see that GDB recognizes the symbol x% because it recognizes and display it's address. But the following "print" fails:
(gdb) print x%
No symbol "x" in current context.
Hmmm... that's interesting ... it dropped the % symbol.
But I can look at the memory location where x% is stored and this looks correct:
(gdb) x 0x4263c4
0x4263c4 <x%>: 0x00000000
If I show all symbols I get this as expected:
(gdb) info variables
All defined variables:
File t.bas:
static i32 x%;
static i32 y%;
static i32 z%;
Continuing on, to show that x% does get modified by the code:
(gdb) n
5 y = 100
(gdb) print x%
No symbol "x" in current context.
(gdb) x 0x4263c4
0x4263c4 <x%>: 0x00000005
(gdb)
And as you can see, the memory that GDB thinks x% is at is definitely updated.
For some reason, the "print" command doesn't like the % symbol.
Here is the "info source" results on this module, you can see I didn't specify C as the language:
(gdb) info source
Current source file is t.bas
Compilation directory is D:\dev\BasicParser
Located in D:\dev\BasicParser\t.bas
Contains 18 lines.
Source language is minimal.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.
Any ideas for workarounds? I've been searching and searching and can't find a solution.
Thanks!
gdb simply interprets your command as modulo operation. It is not an error in gdb.
See, info source shows minimal for your file. This is from gdb's doc: http://sourceware.org/gdb/current/onlinedocs/gdb/Unsupported-Languages.html#Unsupported-Languages
In addition to the other fully-supported programming languages, GDB
also provides a pseudo-language, called minimal. It does not represent
a real programming language, but provides a set of capabilities close
to what the C or assembly languages provide.
So, what does this warning in your debugging session mean?
(gdb) print x%
No symbol "x" in current context.
Since minimal is a set of capabilities close C then gdb must iterpret this as trying to get remainder of division (http://en.wikipedia.org/wiki/Modulo_operation) - according to C programming language rules. So x is left arg, % is operation and the right arg is missing.
Let me show you example. This is a test C++ program that shows the minimal debugging session:
D:\src-c++\tests\test.vars>cat minimal.cpp
int main()
{
int k;
k = 1;
k = 2;
return 0;
}
And this is a debugging session:
D:\src-c++\tests\test.vars>gdb -q minimal.exe
Reading symbols from D:\src-c++\tests\test.vars\minimal.exe...done.
(gdb) start
Temporary breakpoint 1 at 0x4016be: file minimal.cpp, line 5.
Starting program: D:\src-c++\tests\test.vars/minimal.exe
[New Thread 2872.0x8c0]
Temporary breakpoint 1, main () at minimal.cpp:5
5 k = 1;
(gdb) show language
The current source language is "auto; currently c++".
(gdb) set language minimal
Warning: the current language does not match this frame.
(gdb) show language
The current source language is "minimal".
Warning: the current language does not match this frame.
(gdb) n
6 k = 2;
(gdb) print k
$1 = 1
(gdb) print k%
A syntax error in expression, near `'.
(gdb) print kk%
No symbol "kk" in current context.
Look -- No symbol "kk" in current context, the same error that you have.
Just a cross-reference, in case anybody else like me that might need help with this: I found this answer
In GDB, how to print the content of a symbol which has special characters?
where they indicate that you can quote names by starting with ampersand (&) and quote the name with single ticks ('), that is use something like
p &'my#complex.symbol%name'
x &'my#complex.symbol%name'
to inspect symbols with names beyond the usual C-style naming convention. I'm not completely clear what characters you can use at that point, but it seems like a good improvement.
As the other answer also points out, the GDB manual often refers to escaping symbol names just using single ticks (say something like p 'foo.c'). After some further reading I found in the GDB manual that this use of & seems to be an extension added for Windows support (see section titled "Features for Debugging MS Windows PE Executables", numbered 21.1.4 in the current edition), so I'm not sure if this may work outside of the Windows environment

gdb and GPS: Cannot set a breakpoint on a function or procedure that is part of a protected type Ada object

I've got a protected object that presents functions and procedures in its interface.
In gdb, when I set a bp on the first line of one of those, I get odd results.
Here's a snippet from my gdb console:
(gdb)
(gdb) b database-access_manager.adb:20001
Breakpoint 3 at 0x1a10588: file y:/svs/central_switch/controller/database/
database-access_manager.ads, line 20001.
(gdb)
You can see that gdb is confused. I specified a bp at 20001 of the .adb file but gdb responded by saying it had set the bp at 20001 of the corresponding ads file - which doesn't have that many lines.
What gives?
That .ads file wouldn't happen to be defining or using a generic, would it?
I have yet to find a debugger that handles Ada generics very well. The compiler often creates a raft of semi-invisible code that confuses the heck out of debuggers. I suspect C++ templates have the same issue.
Another possibility is that you are looking at a source file that has been modified since your program was compiled.
Running on Windows with GNAT Pro 6.3.1 (I realise this isn't an ideal data point for you!) this worked fine.
I did notice that when I requested a bp on the subprogram specification, GDB effectively set two bps, one in the specification and one at the first statement: so, given
package body Protected_Object is
protected body PO is
procedure Put (V : Integer) is
begin
Value := V;
end Put;
function Get return Integer is
begin
return Value;
end Get;
end PO;
end Protected_Object;
the GDB console says (for Put)
gdb) break protected_object.adb:4
Breakpoint 1 at 0x401729: file protected_object.adb, line 6. (2 locations)
and at run time, sure enough there are 2 breaks:
Breakpoint 1, <protected_object__po__putP> (<_object>=..., v=42) at protected_object.adb:4
(gdb) cont
Breakpoint 1, protected_object.po.put (<_object>=..., v=42) at protected_object.adb:6
Version: GNU gdb (GDB) 7.0.1 for GNAT Pro 6.3.1 (20100112) [rev:158983]
Here's the update on my problem.
I made a protected type with access methods and used it in a small main and found that breakpoints in my example protected type worked fine.
Now I'm trying to understand why, within the context of my company's very large build, the breakpoints don't work.
I'm using the same gdb, GPS, & compiler switches in each case and it works for the small program but not in the large one.
I'll post my results when/if I have any.
Thanks to all the repliers.
Tom