How to print and use constants with gdb (through Xcode)? - cocoa

I am debugging a Cocoa application using xcode-gdb. I am at a break point and I want view the value of some Cocoa constants (ie NSControlKeyMask) and to do some test with the values in the current stackframe. Specifically I am in - (void) keyDown:(NSEvent *) e , and I have done set $mf = (int)[e modifierFlags] on the gdb prompt. Now I want to do p $mf & NSControlKeyMask and gdb is telling me 'No symbol "NSControlKeyMask" in current context.'
UPDATE:
Xcode has the "Fix and Continue text" feature. So I used Dan M. and n8gray solution with this feature so I don't have to make a proxy of every constant.

If no variables are actually instantiated with a given type, then the debug information for the corresponding symbols doesn't wind up getting generated by gcc. Then, if you ask gdb about such a type, it doesn't know what you are talking about because there is no debug information for that type, and it will give you the "No symbol in current context" error.
A workaround to this problem would normally be to explicitly add a dummy variable, of the type in question, somewhere in the code. Here is a simple example that you can test to see what I'm talking about:
enum an_enum_type {
foo,
bar,
baz
};
int main (int argc, char *argv [])
{
return baz;
}
Save that program to a file named test.cpp and compile it with this command:
g++ -o test -g -O0 test.cpp
Then run it under gdb and type "p /x baz". You will get the "No symbol baz in current context" error.
Now try it with this modified version that has added a dummy variable, of the enum type:
enum an_enum_type {
foo,
bar,
baz
};
an_enum_type dummy;
int main (int argc, char *argv [])
{
return baz;
}
Compile with the same command as before and run under gdb. This time when you type "p /x baz" you'll get "0x2" as the answer, which I think is what you are shooting for in your question.
I've looked into it, and the problem is that the NSEvent.h header file doesn't give a name to the enum that contains NSControlKeyMask -- it's an anonymous enum. So there is no way to create a variable of that type (dummy or otherwise). So, I don't see any way of getting the compiler to generate the debug information for that type. I think you're just going to have to rely on the definition of NSControlKeyMask from the header file.

If you compile with gcc you can use the -g3 switch to get the highest level of debug info. Quoting from the section on -g in the gcc manual:
-glevel
Request debugging information and also use level to specify how much information. The default level is 2.
Level 0 produces no debug information at all. Thus, -g0 negates -g.
Level 1 produces minimal information, enough for making backtraces in parts
of the program that you don't plan to debug. This includes descriptions
of functions and external variables, but no information about local
variables and no line numbers.
Level 3 includes extra information, such as all the macro definitions present
in the program. Some debuggers support macro expansion when you use
-g3.
So if you compile with -g3 you should be able to expand constants and macros in gdb.

As Dan M. discovered, you probably can't get this to work in a straightforward way. Instead, what you could do is put something like this in one of your files:
int myNSControlKeyMask = NSControlKeyMask;
int myNSOptionKeyMask = NSOptionKeyMask;
...
Then at least you can use symbolic names in gdb without having to look up the corresponding values in the .h file.

NSControlKeyMask is most likely a macro and invisible to the debugger. You need to look in the appropriate .h file. Place the cursor over the text NSControlKeyMask in the editor and try command+double-click to jump to its definition.

I seem to be getting the same problem in a bunch of C++ code that is being called from Obj-C in an iPhone app. It's giving me the
No symbol "a" in current context.
error, where a is an int. I tried the -g3 compiler flag with no success. I find it hard to believe gdb doesn't know the type of an int. SDK 3.0, but then again, gdb was printing completely erroneous values when it could find variable in the program.

Related

Does CLion possible evaluate a function when debugging Rust code?

A snip of Rust code:
pub fn main() {
let a = "hello";
let b = a.len();
let c =b;
println!("len:{}",c)
}
When debugging in CLion, Is it possible to evaluate a function? For example, debug the code step by step, now the code is running to the last line println!... and the current step stops here, by adding the expression a.len() to the watch a variable window, the IDE can't evaluate the a.len(). It says: error: no field named len
This is the same reason you can't make conditional breakpoints for Rust code:
Can't create a conditional breakpoint in VSCode-LLDB with Rust
I hope, I'm not too late to answer this, but with both lldb and gdb, Rust debugging capability is currently rather constrained.
Expressions that are straightforward work; anything complex is likely to produce issues.
My observations from rust-lldb trying this, are that only a small portion of Rust is understood by the expression parser.
There is no support for macros.
Non-used functions are not included in the final binary.
For instance, since that method is not included in the binary, you are unable to execute capacity() on the HashMap in the debugger.
Methods must be named as follows:
struct value.method(&struct value)
There is no technique that I've discovered to call monomorphized functions on generic structs (like HashMap).
For example, "hello" is a const char [5] including the trailing NUL byte. String constants "..." in lldb expressions are produced as C-style string constants.
Therefore, they are not valid functions

Expression result unused: strange behaviour of c++ compiler?

I accidentally typed the following code but my code successfully built and even ran properly.
std::string myString = "This is my string ";
std::shared_ptr<std::string> s = std::make_shared<std::string>(myString);
p->pushString(s);”accidental typo”;
It just showed a warning Expression result unused.
Why it is not a compiler or run time error?
I am using Xcode editor
Thanks
Why it is not a compiler [...] error?
Because it does not violate any rule of the C++ standard. If a program conforms to the standard then the compiler should allow its compilation. However, it was friendly enough to warn you that the expression is useless.
or run time error?
The expression doesn't result in any executed code, so it would be quite surprising if it resulted in a run time error.
You know that you can have arbitrary expressions as statements? That's how simple functions calls works, or assignments. In fact the statement
p->pushString(s);
is actually such an expression-statement. The p->pushString(s) part is an expression, it's the context (with the terminating semi-colon) that turns it into a statement.
That also means you can do something like
5;
Or in your case
"some string here";
Those are valid statements. They do however produce a result, which is (legally) discarded or ignored, but might cause the compiler to emit a warning about the ignored result.
It's really no different than e.g.
some_function_which_returns_a_result(); // Result ignored

How do I quickly inspect the value of an arbitrary variable in Xcode 4.6.x?

It seems reasonably widely acknowledged that it is slow to use the po command in Xcode 4.6.x. What are the options for inspecting the values of arbitrary variables unspecified at compile time (which rules out usage of NSLog()) which don't take > 15s?
Just set a breakpoint where you want to learn the variables' value. Once the program is paused, a summary of all the variables' value will appear on the Varibles view on the left-bottom of the screen. Here is a screenshot :
You can use the lldb commands:
p (int) myInt
po myObject
po myObject.memberObject
p (float) myObject.floatMember
Just a note, you could also use p instead of po in the newest version of Xcode. If you run the help -a in llb, it will present you with command aliases, below is a snippet of the commands you could use.
> (lldb) help -a
p -- ('expression --') Evaluate a C/ObjC/C++ expression in the current
program context, using user defined variables and variables
currently in scope.
po -- ('expression -o --') Evaluate a C/ObjC/C++ expression in the
current program context, using user defined variables and
variables currently in scope
print -- ('expression --') Evaluate a C/ObjC/C++ expression in the current
program context, using user defined variables and variables
currently in scope.
Turns out the answer is pretty simple: download Xcode 4.6.2 where LLDB debugging speed has been increased significantly. Note some discussion over here

LLVM equivalent of gcc's __BIGGEST_ALIGNMENT__?

GCC provides a __BIGGEST_ALIGNMENT__ pre-defined macro which is the largest alignment ever used for any data type on the target machine you are compiling for. I cannot seem to find an LLVM's equivalent for this. Is there any? If not, what is the best way to figure it out (preferably with pre-processor)?
This isn't accessible from the preprocessor, but __attribute__((aligned)) or __attribute__((__aligned__)) (with the alignment value omitted) will give the alignment you want. This is supposed to give the largest alignment of any built-in type, which is 16 on x86 and ARM.
For example:
$ cat align.c
struct foo {
char c;
} __attribute__((aligned)) var;
$ clang align.c -S -o - -emit-llvm
...
#var = global %struct.foo zeroinitializer, align 16
This is used by unwind.h for _Unwind_Exception:
struct _Unwind_Exception
{
_Unwind_Exception_Class exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
_Unwind_Word private_1;
_Unwind_Word private_2;
/* ### The IA-64 ABI says that this structure must be double-word aligned.
Taking that literally does not make much sense generically. Instead we
provide the maximum alignment required by any type for the machine. */
} __attribute__((__aligned__));
This is in llvm internals as TargetData::PointerABIAlign, but it doesn't appear to be exposed to code. I'd just hard code to 16 bytes, as it seems like it'd be a while before we see any more aligned types or instruction sets.

How to get warnings of incorrect string formatting (C++)

apologies in advance if i use poor terminology.
when i compile a C++ app under gdb and use printf() it gives me awesome warnings relating to the consistency of the format string and the arguments passed in.
eg, this code:
printf("%s %s", "foo");
results in a compiler warning "too few arguments for format", which is super-useful.
it will also give warnings about format string type vs. argument type.
it must have inspected the format string and compared that against the supplied argument types.
- is this sort of compile-time introspection something which can be added to ordinary source code, or is it something which needs to be compiled into gcc itself ?
fwiw this is under gcc 4.2.1 on os x.
You can do stuff like this for your own printf-like functions (as well as for scanf/strftime/strfmon-like functions):
#define PRINTF_FORMAT_CHECK(format_index, args_index) __attribute__ ((__format__(printf, format_index, args_index)))
void my_printf(const char *fmt, ...) PRINTF_FORMAT_CHECK(1, 2);
See the gcc manual for further details.

Resources