Const variables are good. However, sometimes I want to dynamically change their values when debugging to trace some specific behavior.
When I po flag = NO I receive this error:
error: <user expression 0>:1:34: cannot assign to variable 'flag' with const-qualified type 'const BOOL &' (aka 'const bool &')
Is there any workaround?
You can make the expression succeed by using const_cast, but it is likely to not do what you want. For instance:
(lldb) run
Process 32640 launched: '/tmp/foo' (x86_64)
Process 32640 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x0000000100003f66 foo`main at foo.c:7
4 main()
5 {
6 const int foo = 10;
-> 7 printf("%d\n", foo);
^
8 return 0;
9 }
Target 0: (foo) stopped.
(lldb) expr foo = 20
error: <user expression 0>:1:5: cannot assign to variable 'foo' with const-qualified type 'const int &'
foo = 20
~~~ ^
note: variable 'foo' declared const here
const_cast to the rescue:
(lldb) expr *(const_cast<int*>(&foo)) = 20
(int) $1 = 20
We really did change the value in the foo slot, as you can see by:
(lldb) expr foo
(const int) $2 = 20
and:
(lldb) frame var foo
(const int) foo = 20
But the compiler is free to inline the value of const variables, which it does pretty freely even at -O0 (*). For instance, the call to printf compiled on x86_64 at -O0 to:
-> 0x100003f66 <+22>: leaq 0x39(%rip), %rdi ; "%d\n"
0x100003f6d <+29>: movl $0xa, %esi
0x100003f72 <+34>: movb $0x0, %al
0x100003f74 <+36>: callq 0x100003f86 ; symbol stub for: printf
Note that it doesn't reference any variables, it just puts 0xa into the second argument passing register directly. So unsurprisingly:
(lldb) c
Process 33433 resuming
10
(*) At higher optimization levels there probably wouldn't even be a variable allocated on the frame for const variables. The value would just get inserted immediately as above, and the debug information would also record it for the debugger's display, but there wouldn't be anything in memory to change from the old to the new value.
Related
I've asked people before about why the stack doesn't start at 0x7fff...c before, and was told that typically 0x800... onwards is for the kernel, and the cli args and environment variables live at the top of the user's stack which is why it starts below 0x7fff...c. But I recently tried to examine all the strings with the following program
#include <stdio.h>
#include <string.h>
int main(int argc, const char **argv) {
const char *ptr = argv[0];
while (1) {
printf("%p: %s\n", ptr, ptr);
size_t len = strlen(ptr);
ptr = (void *)ptr + len + 1;
}
}
However, after displaying all my environment variables, I see the following (I compiled the program to an executable called ./t):
0x7ffc19f84fa0: <final env variable string>
0x7ffc19f84fee: _=./t
0x7ffc19f84ff4: ./t
0x7ffc19f84ff8:
0x7ffc19f84ff9:
0x7ffc19f84ffa:
0x7ffc19f84ffb:
0x7ffc19f84ffc:
0x7ffc19f84ffd:
0x7ffc19f84ffe:
0x7ffc19f84fff:
So it appears there's one extra empty byte after the null terminator for the ./t string at bytes 0x7ffc19f84ff4..0x7ffc19f84ff7, and after that I segfault so I guess that's the base of the stack. What actually lives in the remaining "empty" space before kernel memory starts?
Edit: I also tried the following:
global _start
extern print_hex, fgets, puts, print, exit
section .text
_start:
pop rdi
mov rcx, 0
_start_loop:
mov rdi, rsp
call print_hex
pop rdi
call puts
jmp _start_loop
mov rdi, 0
call exit
where print_hex is a routine I wrote elsewhere. It seems this is all I can get
0x00007ffcd272de28
./bin/main
0x00007ffcd272de30
abc
0x00007ffcd272de38
def
0x00007ffcd272de40
ghi
0x00007ffcd272de48
make: *** [Makefile:47: run] Segmentation fault
so it seems that even in _start we don't begin at 0x7fff...
I have a block of code that I want to #include in my z/OS Metal C program, it works fine when it's just part of the program, but when I put it into a .h file and #include it, the code won't compile.
I have successfully gotten this code to work without #include. I'm sure I'm overlooking something having to do with #include...
This code works:
#pragma margins(2,72)
*#if 0!=0
Test DSECT
Test# DS A
TestINT DS F
TestChar DS C
.ago end
*#endif
*struct Test {
* void *Test1;
* int TestInt;
* char TestChar;
*};
*#if 0!=0
.end
MEND
*#endif
#pragma nomargins
Giving compiler output that looks like this:
207 |#pragma margins(2,72)
207 +
208 |#if 0!=0
214 |#endif
215 |struct Test {
216 | void *Test1;
5650ZOS V2.1.1 z/OS XL C 'SSAF.METALC.C(CKKTHING)'
* * * * * S O U R C E * * * * *
LINE STMT
*...+....1....+....2....+....3....+....4....+....5....+....6....+
217 | int TestInt;
218 | char TestChar;
219 |};
220 |#if 0!=0
223 |#endif
224 |#pragma nomargins
But, when I put the code into an #include file like this:
EDIT SSAF.METALC.H(CKKTEST)
Command ===>
****** **************************
000001 *#if 0!=0
000002 Test DSECT
000003 Test# DS A
000004 TestINT DS F
000005 TestChar DS C
000006 .ago end
000007 *#endif
000008 *struct Test {
000009 * void *Test1;
000010 * int TestInt;
000011 * char TestChar;
000012 *};
000013 *#if 0!=0
000014 .end
000015 MEND
000016 *#endif
****** **************************
and include it in my Metal C program:
EDIT SSAF.METALC.C(CKLTHING) - 01.00
Command ===>
000205 #include"ckkprolg.h"
000206
000207 #pragma margins(2,72)
000208 #include"ckktest.h"
000209 #pragma nomargins
I get a bunch of error messages:
205 |#include"ckkprolg.h" /* Include assembler macros needed
206 | for Metal C prolog and epilog */
207 |#pragma margins(2,72)
207 +
208 |#include"ckktest.h"
*=ERROR===========> CCN3275 Unexpected text 'struct' encountered.
*=ERROR===========> CCN3166 Definition of function Test requires parentheses.
*=ERROR===========> CCN3275 Unexpected text 'void' encountered.
5650ZOS V2.1.1 z/OS XL C 'SSAF.METALC.C(CKLTHING)' 10/04/2019
* * * * * S O U R C E * * * * *
LINE STMT
*...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9...
*=ERROR===========> CCN3045 Undeclared identifier Test1.
*=ERROR===========> CCN3275 Unexpected text 'int' encountered.
*=ERROR===========> CCN3045 Undeclared identifier TestInt.
*=ERROR===========> CCN3275 Unexpected text 'char' encountered.
*=ERROR===========> CCN3045 Undeclared identifier TestChar.
*=ERROR===========> CCN3046 Syntax error.
*=ERROR===========> CCN3273 Missing type in declaration of theESTAEXStatic.
209 |#pragma nomargins
The include file is missing #pragma margins. Since it is a file level directive, it needs to be present in each source file. Please see IBM Knowledge Center, which says, "The setting specified by the #pragma margins directive applies only to the source file or include file in which it is found. It has no effect on other include files."
I am adding a breakpoint in lldb like so:
(lldb) breakpoint set -s MyApp --func-regex .
(lldb) breakpoint command add 1
Enter your debugger command(s). Type 'DONE' to end.
> p __PRETTY_FUNCTION__
> continue
> DONE
(lldb) process attach --name MyApp --waitfor
(lldb) continue
My goal is to print each of the methods called in the my app. The results looks like:
(lldb) p __PRETTY_FUNCTION__
(const char [26]) $0 = "void $__lldb_expr(void *)"
(lldb) continue
Process 96238 resuming
Command #1 'continue' continued the target.
(lldb) p __PRETTY_FUNCTION__
(const char [47]) $1 = "-[AppDelegate($__lldb_category) $__lldb_expr:]"
(lldb) continue
Process 96238 resuming
Command #1 'continue' continued the target.
(lldb) p __PRETTY_FUNCTION__
(const char [47]) $2 = "-[AppDelegate($__lldb_category) $__lldb_expr:]"
(lldb) continue
Process 96238 resuming
Command #1 'continue' continued the target.
(lldb) p __PRETTY_FUNCTION__
(const char [47]) $3 = "-[AppDelegate($__lldb_category) $__lldb_expr:]"
(lldb) continue
Process 96238 resuming
Command #1 'continue' continued the target.
(lldb) p __PRETTY_FUNCTION__
(const char [47]) $4 = "-[AppDelegate($__lldb_category) $__lldb_expr:]"
(lldb) continue
The question is how do I remove the $__lldb_category and the $__lldb_expr: with the actual values of the method name and it's selectors?
I would use lldb commands to print this information, for instance:
(lldb) frame info
frame #0: 0x0000000100018dc7 Sketch`main(argc=1, argv=0x00007fff5fbff628) + 55 at SKTMain.m:17
would do what you want I think. If you want more or less info, you can also tailor the output of frame info as described here:
http://lldb.llvm.org/formats.html
I have written some code that changes the current stack used by modifying the stack pointer in inline assembly. Although I can call functions and create local variables, calls to println! and some functions from std::rt result in the application terminating abnormally with signal 4 (illegal instruction) in the playpen. How should I improve the code to prevent crashes?
#![feature(asm, box_syntax)]
#[allow(unused_assignments)]
#[inline(always)]
unsafe fn get_sp() -> usize {
let mut result = 0usize;
asm!("
movq %rsp, $0
"
:"=r"(result):::"volatile"
);
result
}
#[inline(always)]
unsafe fn set_sp(value: usize) {
asm!("
movq $0, %rsp
"
::"r"(value)::"volatile"
);
}
#[inline(never)]
unsafe fn foo() {
println!("Hello World!");
}
fn main() {
unsafe {
let mut stack = box [0usize; 500];
let len = stack.len();
stack[len-1] = get_sp();
set_sp(std::mem::transmute(stack.as_ptr().offset((len as isize)-1)));
foo();
asm!("
movq (%rsp), %rsp
"
::::"volatile"
);
}
}
Debugging the program with rust-lldb on x86_64 on OS X yields 300K stack traces, repeating these lines over and over:
frame #299995: 0x00000001000063c4 a`rt::util::report_overflow::he556d9d2b8eebb88VbI + 36
frame #299996: 0x0000000100006395 a`rust_stack_exhausted + 37
frame #299997: 0x000000010000157f a`__morestack + 13
morestack is assembly for each platform, like i386 and x86_64 — the i386 variant has more description that I think you will want to read carefully. This piece stuck out to me:
Each Rust function contains an LLVM-generated prologue that compares the stack space required for the current function to the space remaining in the current stack segment, maintained in a platform-specific TLS slot.
Here's the first instructions of the foo method:
a`foo::h5f80496ac1ee3d43zaa:
0x1000013e0: cmpq %gs:0x330, %rsp
0x1000013e9: ja 0x100001405 ; foo::h5f80496ac1ee3d43zaa + 37
0x1000013eb: movabsq $0x48, %r10
0x1000013f5: movabsq $0x0, %r11
-> 0x1000013ff: callq 0x100001572 ; __morestack
As you can see, I am about to call into __morestack, so the comparison check failed.
I believe that this indicates that you cannot manipulate the stack pointer and attempt to call any Rust functions.
As a side note, let's look at your get_sp assembly:
movq %rsp, $0
Doing a check check for the semantics of movq:
Copies a quadword from the source operand (second operand) to the destination operand (first operand).
That seems to indicate that your assembly is backwards, in addition to all the other problems.
I am new to gdb. I want to print the memory addresses used with the actual sequence during execution of a c program. Let’s explain my question with an example. Let’s assume that we have the following c code with two functions main() and test(). I know that, inside gdb, I can use "disassemble main" to disassemble main() function, or "disassemble test" to disassemble test() function separately. My question is, how can I disassemble these two functions as a single code; so that, I can see all the memory addresses used during execution and their sequence of accesses? To be specific, as main() is calling test() and test() is also calling itself multiple times, I want to see something like example 2. I am also wandering, the addresses shown in gdb disassembler, are they virtual or physical memory addresses? Any help or guidance will be appreciated.
Example 1:
#include "stdio.h"
int test(int q)
{
if(q<16)
test(q+5);
return q;
}
void main()
{
unsigned int a=5;
unsigned int b=5;
unsigned int c=5;
test(a);
}
Example 2:
<Memory Address> <assembly instruction> <c instructions>
0x12546a mov //for unsigned int a=5;
0x12546b mov //for unsigned int b=5;
0x12546c mov //for unsigned int c=5;
0x12546d jmp //for test(q=a=5);
0x12546e cmpl //for if(q<16)
0x12546f jmp //for test(q+5);
0x12546d jmp //for test(q=10);
0x12546e cmpl //for if(q<16)
0x12546f jmp //for test(q+5);
0x12547a jmp //for test(q=15);
0x12547b cmpl //for if(q<16)
0x12547c jmp //for test(q+5);
0x12547d jmp //for test(q=20);
0x12547e cmpl //for if(q<16)
0x12547f jmp //return q);
0x12548a jmp //return q);
0x12548b jmp //return q);
0x12548c jmp //return q);
There's really no pretty way to do this. You're just going to have to step through the code:
(gdb) stepi
(gdb) x/i $pc
(gdb) info registers
(gdb) stepi
(gdb) x/i $pc
(gdb) info registers
.....
You could script that up so that it does it quickly and dumps the data to a file, but that's about all.
I suppose you may have more luck with valgrind. If there's no existing tool to do so, it is possible to add your own instrumentation to report memory accesses (and not only that), or alter an existing one.
E.g. see http://valgrind.org/docs/manual/lk-manual.html
--trace-mem= [default: no]
When enabled, Lackey prints the size and address of almost every memory access made by the program.