QtCreator debugger does not display values of std::string - c++

I tried to debug my small little lexer and ran into this problem: the QtCreator-Debugger does not display any content of my std::string-variable. I tried to debug it in console and I got the same result, just plain structure information.
The version of QtCreator I used a few days ago did display the content of the strings. All other STL-Elements like std::vector, std::map, std::multimap, etc. display the correct data, it's just the std::string class which does not do the right.
After several hours of googling I found a lot of web pages which describe the creation of pretty printers, my really noobish approaches to fix this didn't help. Any ideas how I can get rid of this bug?
Note: The 'content' of the string-variables will always be displayed as 'not accessible'.
I use QtCreator 2.6 (QT5) for 64bit Linux OS.
Edit(1): I reinstalled everything from OS to Compilers and IDE... The strange is, when I build my project with optimization level 3 (-O3) QT can display std::strings.
The command line is the following:
clang++ -std=c++11 -O3 -g -c foo.cpp
When I remove -O3 std::strings are < not accessible >. Any ideas?

You can try to fix "/usr/share/qtcreator/debugger/stdtypes.py". As they use "hard-code assumption on member position" it seems like not working everywhere.
In my case - Linux x64, gcc 9.1 it works exactly like you described:
string not accessible
So find function def qdumpHelper_std__string(d, value, charType, format):
And change
(size, alloc, refcount) = d.split("ppp", data - 3 * d.ptrSize())
to
(size, alloc, refcount) = d.split("ppp", value.address() + d.ptrSize())
Also comment d.check(0 <= size and size <= alloc and alloc <= 100*1000*1000) or change it to something like
if size > 1000:
size = 1000
On my system std::string has next structure
pointer 8 byte
size 8 byte
union 16 byte
And this union field can change its meaning depends on string size. So we need to comment that size < alloc check.
value.address() - the address of the string object, so value.address() + d.ptrSize()will point to size, and value.address() + 2 * d.ptrSize() point to that union, which contain alloc size value, from time to time.
Just look at your std::string class declaration so you will get structure on your system.
And after the fix:
fixed debuger view
Works both - when "system GDB pretty printers" checked and clear

Try this, it worked for me.
In Qt Creator menu bar:
Tools -> Options -> Debugger
Uncheck the option (Load system GDB pretty printers)

To clarify and sum up AstoBasto post:
In file: /usr/share/qtcreator/debugger/stdtypes.py replace this function:
def qdumpHelper_std__string(d, value, charType, format):
[...]
With this:
def qdumpHelper_std__string(d, value, charType, format):
if d.isQnxTarget():
qdumpHelper__std__string__QNX(d, value, charType, format)
return
if d.isMsvcTarget():
qdumpHelper__std__string__MSVC(d, value, charType, format)
return
data = value.extractPointer()
# We can't lookup the std::string::_Rep type without crashing LLDB,
# so hard-code assumption on member position
# struct { size_type _M_length, size_type _M_capacity, int _M_refcount; }
(size, alloc, refcount) = d.split("ppp", value.address() + d.ptrSize())
refcount = refcount & 0xffffffff
d.check(refcount >= -1) # Can be -1 according to docs.
if size > 4002:
size = 4002
d.putCharArrayHelper(data, size, charType, format)
And this works (at least on Kubuntu 19.10).

Related

C++ gdb: How to display a range of elements in a vector and within that range, a subset of the elements' members?

This answer is based on a comment by bcumming in How do I print the elements of a C++ vector in GDB? and was tested with Codelite 10.0.0, gcc 4.9.2 and gdb 7.7.1 on 64 bit Debian 8. That question concerned displaying all the elements of the vector. The answer by John Carter had the disadvantage of involving internal library-dependent pointer names and the advantage that it works fine even if the inferior (the program being debugged) did not have compiled into it the code for operator [ ]. (See: gdb Could not find operator[].)
If I want to see 4 elements of vector vecVp starting with index [3] then the gdb print command is:
p *(&vecV[3]) # 4
This is my answer. I have been trying to figure out how to do this for years, and it is not in the gdb manual, as far as I know. The text below concerns variations of and the principles behind this technique.
One reason for doing this is to reduce the clutter of displaying all the elements of a vector. The other is to reduce the time it takes gdb to respond for the Watch window lines, such as for each "step over" IDE operation. I find that gdb, with its Python-based STL pretty printing mechanisms, can take seconds or tens of seconds to respond to large numbers of simple elements, or few more complex ones.
This is an application to vectors of the technique described in gdb manual section 10.4 Artificial Arrays where the binary operator # works fine with C-style arrays: p arrA[3] # 4 but not vectors and the like from the containers library (STL).
The above use of #, starting with a particular vector element, works fine in Codelite's Watch window, where the p part above is not needed. The single line which Codelite displays can be opened up by clicking right-pointing arrows to show all the values of the elements and the objects, vectors of strings etc. that they contain. However, it does not work as the basis for displaying just just one inner element, such as some class object, an int or a string, of each of the range of vector elements. To do this, four Watch lines must be created (add p for driving gdb directly):
vec[3].log
vec[4].log
vec[5].log
vec[6].log
This of course is tedious. The solution is to add some variables to the inferior which are only to be used by gdb. These can be static, outside any function and so "global":
static int XX = 0;
static int YY = 0;
static int ZZ = 0;
Their values can be set from within Codelite, while the inferior is paused at a breakpoint, by commands such as set XX = 3 entered into the "Send" bar at the bottom of the gdb console, which is under the "(red ladybug icon) Output" tab of the "Debugger" window. This enables me to use four Watch lines, each focused on just the "log" member of the four chosen elements in the vector, which can be easily steered to any part of the vector by altering the value of XX:
vecV[XX + 0].log
vecV[XX + 1].log
vecV[XX + 2].log
vecV[XX + 3].log
What's more, in my experience, changing XX causes Codelite to not only display the new data, but to highlight in red any which is different from what it displayed with the previous value of XX.
If log was an object containing a string which was too long to view in the Watch window (Settings > GDB Settings > GNU gdb debugger > General > Display > Number of elements to display for arrays/strings), then I can use the above scheme and substr() with some other gdb-set variables to control which range of the strings are displayed:
vecV[XX + 0].log.strS.substr(AA, BB)
vecV[XX + 1].log.strS.substr(AA, BB)
vecV[XX + 2].log.strS.substr(AA, BB)
vecV[XX + 3].log.strS.substr(AA, BB)
Such variables can be applied to the main technique to provide a steerable, resizable, window of display into a vector, by typing one or two commands to the gdb console, rather than editing the Watch window line, which typically involves lots of mouse/trackball clicking to re-open all the branches of the objects which are of interest:
(&vecV[YY]) # ZZ

Add specific string to core dump to the beginning of it

I have a large coredumps, say, 120+ Gigabytes.
I need to get program version from it, so I add global constant (pseudo code):
static const char* const = "MAGIC_KEYWORD_FOR_GREPPING_" + MY_PROGRAM_VERSION;
Is it possible to place it to beginning of coredump, so grepping will be faster?
Coredumps are created by the operating system, not by applications that cause them. There is no way for the OS to know the value of some variable in your program. You can adjust the names of your coredumps by setting core_pattern to have the executable name in the coredump's filename included. This man page has the specifiers' description.
It might be that your OS generates coredumps by piping through some application - if cat /proc/sys/kernel/core_pattern returns a string starting with | (for example mine is |/usr/share/apport/apport %p %s %c %P) then you have to adjust the parameters accordingly. See this link for more details

Converting bits from one array to another?

I am building a library for this vacuum fluorescent display. Its a very simple interface and I have all the features working.
The problem I am having now is that I am trying to make the code as compact as possable, but the custom character loading is not intuitive. That is the bitmap for the font maps to completely different bits and bytes to the display itself. From the IEE VFD datasheet, when you scroll down you see that the bits are mapped all over the place.
The code I have so far works like so:
// input the font bitmap, the bit from that line of the bitmap and the bit it needs to go to
static unsigned char VFD_CONVERT(const unsigned char* font, unsigned char from, unsigned char to) {
return ((*font >> from) & 0x01) << to;
//return (*font & (1 << from)) ? (1<<to) : 0;
}
// macros to make it easyer to read and see
#define CM_01 font+0, 4
#define CM_02 font+0, 3
#define CM_03 font+0, 2
#define CM_04 font+0, 1
#define CM_05 font+0, 0
// One of the 7 lines I have to send
o = VFD_CONVERT(CM_07,6) | VFD_CONVERT(CM_13,5) | VFD_CONVERT(CM_30,4) | VFD_CONVERT(CM_23,3) | VFD_CONVERT(CM_04,2) | VFD_CONVERT(CM_14,1) | VFD_CONVERT(CM_33,0);
send(o);
This is oviously not all the code. You can see the rest over my Google code repository but it should give you some idea what I am doing.
So the question I have is if there is a better way to optimize this or do the translation?
Changing the return statement on VFD_CONVERT makes GCC go crazy (-O1, -O2, -O3, and -Os does it) and expands the code to 1400 bytes. If I use the return statement with the inline if, it reduces it to 800 bytes. I have been going though the asm generated statements and current I am tempted to just write it all in asm as I am starting to think the compiler doesn't know what it is doing. However I thought maybe its me and I don't know what I am doing and so it confuses the compiler.
As a side note, the code there works, both return statements upload the custom character and it gets displayed (with a weird bug where I have to send it twice, but that's a separate issue).
First of all, you should file a bug report against gcc with a minimal example, since -Os should never generate larger code than -O0. Then, I suggest storing the permutation in a table, like this
const char[][] perm = {{ 7, 13, 30, 23, 4, 14, 33}, ...
with special values indicating a fixed zero or one bit. That'll also make your code more readable.

Retrieve RAM info on a Mac?

I need to retrieve the total amount of RAM present in a system and the total RAM currently being used, so I can calculate a percentage. This is similar to: Retrieve system information on MacOS X?
However, in that question the best answer suggests how to get RAM by reading from:
/usr/bin/vm_stat
Due to the nature of my program, I found out that I am not cannot read from that file - I require a method that will provide me RAM info without simply opening a file and reading from it. I am looking for something to do with function calls. Something like this preferably : getTotalRam() and getRamInUse().
I obviously do not expect it to be that simple but I was looking for a solution other than reading from a file.
I am running Mac OS X Snow Leopard, but would preferably get a solution that would work across all current Mac OS X Platforms (i.e. Lion).
Solutions can be in C++, C or Obj-C, however C++ would the best possible solution in my case so if possible please try to provide it in C++.
Getting the machine's physical memory is simple with sysctl:
int mib [] = { CTL_HW, HW_MEMSIZE };
int64_t value = 0;
size_t length = sizeof(value);
if(-1 == sysctl(mib, 2, &value, &length, NULL, 0))
// An error occurred
// Physical memory is now in value
VM stats are only slightly trickier:
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
vm_statistics_data_t vmstat;
if(KERN_SUCCESS != host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmstat, &count))
// An error occurred
You can then use the data in vmstat to get the information you'd like:
double total = vmstat.wire_count + vmstat.active_count + vmstat.inactive_count + vmstat.free_count;
double wired = vmstat.wire_count / total;
double active = vmstat.active_count / total;
double inactive = vmstat.inactive_count / total;
double free = vmstat.free_count / total;
There is also a 64-bit version of the interface.
You're not supposed to read from /usr/bin/vm_stat, rather you're supposed to run it; it is a program. Look at the first four lines of output
Pages free: 1880145.
Pages active: 49962.
Pages inactive: 43609.
Pages wired down: 123353.
Add the numbers in the right column and multiple by the system page size (as returned by getpagesize()) and you get the total amount of physical memory in the system in bytes.
vm_stat isn't setuid on Mac OS, so I assume there is a non-privileged API somewhere to access this information and that vm_stat is using it. But I don't know what that interface is.
You can figure out the answer to this question by looking at the source of the top command. You can download the source from http://opensource.apple.com/. The 10.7.2 source is available as an archive here or in browsable form here. I recommend downloading the archive and opening top.xcodeproj so you can use Xcode to find definitions (command-clicking in Xcode is very useful).
The top command displays physical memory (RAM) numbers after the label "PhysMem". Searching the project for that string, we find it in the function update_physmem in globalstats.c. It computes the used and free memory numbers from the vm_stat member of struct libtop_tsamp_t.
You can command-click on "vm_stat" to find its declaration as a membor of libtop_tsamp_t in libtop.h. It is declared as type vm_statistics_data_t. Command-clicking that jumps to its definition in /usr/include/mach/vm_statistics.h.
Searching the project for "vm_stat", we find that it is filled in by function libtop_tsamp_update_vm_stats in libtop.c:
mach_msg_type_number_t count = sizeof(tsamp->vm_stat) / sizeof(natural_t);
kr = host_statistics(libtop_port, HOST_VM_INFO, (host_info_t)&tsamp->vm_stat, &count);
if (kr != KERN_SUCCESS) {
return kr;
}
You will need to figure out how libtop_port is set if you want to call host_statistics. I'm sure you can figure that out for yourself.
It's been 4 years but I just wanted to add some extra info on calculating total RAM.
To get the total RAM, we should also consider Pages occupied by compressor and Pages speculative in addition to Kyle Jones answer.
You can check out this post for where the problem occurs.

How to print subscripts/superscripts on a CLI?

I'm writing a piece of code which deals with math variables and indices, and I'd need to print subscripts and superscripts on a CLI, is there a (possibly cross-platform) way to do that? I'm working in vanilla C++.
Note: I'd like this to be cross-platform, but since from the first answers this doesn't seem to be possible I'm working under MacOS and Ubuntu Linux (so bash).
Thank you
Since most CLIs are really only terminals (pretty dumb ones mostly but sometimes with color), the only cross-platform way I've ever done this is by allocating muliple physical lines per virtual line, such as:
2
f(x) = x + log x
2
It's not ideal but it's probably the best you're going to get without a GUI.
Following you extra information as to what platforms you're mainly interested in:
With Ubuntu at least, gnome-terminal runs in UTF-8 mode by default so the following code shows how to generate the superscripts and subscripts:
#include <stdio.h>
static char *super[] = {"\xe2\x81\xb0", "\xc2\xb9", "\xc2\xb2",
"\xc2\xb3", "\xe2\x81\xb4", "\xe2\x81\xb5", "\xe2\x81\xb6",
"\xe2\x81\xb7", "\xe2\x81\xb8", "\xe2\x81\xb9"};
static char *sub[] = {"\xe2\x82\x80", "\xe2\x82\x81", "\xe2\x82\x82",
"\xe2\x82\x83", "\xe2\x82\x84", "\xe2\x82\x85", "\xe2\x82\x86",
"\xe2\x82\x87", "\xe2\x82\x88", "\xe2\x82\x89"};
int main(void) {
int i;
printf ("f(x) = x%s + log%sx\n",super[2],sub[2]);
for (i = 0; i < 10; i++) {
printf ("x%s x%s ", super[i], sub[i]);
}
printf ("y%s%s%s z%s%s\n", super[9], super[9], super[9], sub[7], sub[5]);
return 0;
}
The super and sub char* arrays are the UTF-8 encodings for the Unicode code points for numeric superscripts and subscripts (see here). The given program will output my formula from above (on one line instead of three), then another test line for all the choices and a y-super-999 and z-sub-75 so you can see what they look like.
MacOS doesn't appear to use gnome-terminal as a terminal program but references here and here seem to indicate the standard terminal understands UTF-8 (or you could download and install gnome-terminal as a last resort).
I'd need to print subscripts and superscripts on a CLI, is there a cross-platform way to do that?
Only if you have a Unicode-capable terminal, which is far from guaranteed. Unicode defines a limited number of sub- and superscript ‘compatibility characters’, you certainly can't use it on any old letter:
₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎ₐₑₒₓ
⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿⁱ
Even then you're reliant on there being a glyph for it in the console font, which is also far from guaranteed. Superscript 2 and 3 are likely to exist as they're present in ISO-8859-1; the others may well not work.