The x command can examine memory in GDB. Like
x/4xg 0x60400
Now I am going to define my own x comand which examines memory with specified repeat count, like:
define myXCommand
set var &repeatCount=$arg0
x/(???)xg 0x60400
end
I have tried many ways to pass the variant repeatCount to x command, but I failed finally. My problem is how to pass the repeat count to x command? Appreciated very much if anyone can help.
A convenience variable can be used in most expressions, but the x command only allows the repeat count to be a string of digits, not an arbitrary expression.
What you can do is use the eval command, which does a printf on its arguments and then runs the result as a command.
define myXCommand
set var $repeatCount=$arg0
eval "x/%dxg 0x60400", $repeatCount
end
Related
I have an real-time OO program (nevertheless written in C) that I am trying to debug. I have an issue that some objects out of thousands get corrupted during a specific window of time, every now and then. I want to have one breakpoint at the start of the window, which automatically sets a watchpoint on a member variable, and then have that watchpoint removed at the end of the window by another breakpoint. The trouble is I need some way of tying a watchpoint number to a given object. If I could construct a convenience variable by some mechanism so that, for example, if $var=28, then set $x${var}=watch -l foo would be the equivalent of set $x28=watch -l foo. (which doesn't actually work) This would allow me to do this:
breakpoint obj_init+23
command
$var = *obj
$x${var} = watch -l foo
continue
done
breakpoint obj_final
command
$var = *obj
delete $x${var}
continue
done
So I don't (hopefully) overrun the number of available hardware watchpoints.
Does anyone know how I might achieve this without trying to write a python extension? (My python is very rusty.)
You can use GDB's eval command to set and use variables whose names are composed of the results of numeric or string expressions.
You can think of eval as doing a printf of its arguments and then executing the resulting string. eval "set var $x%d = 1", 5 will run the command set var $x5 = 1.
The other piece of info you need is that the watch command, as with all breakpoint commands, will set the convenience variable $bpnum to the breakpoint number.
break obj_init+23
commands
set var $var = *obj
watch -l foo
eval "set var $x%d = $bpnum", $var
continue
done
break obj_final
commands
set var $var = *obj
eval "delete $x%d", $var
continue
done
How can I repeatedly run a command in LLDB for debugging C++ code?
For example, when I set a breakpoint inside a loop and want to continue for 10 iterations before stopping, I am currently typing continue ten times manually to do this. Is there a better way?
As an example, let's say I have this code block:
int i = 0;
while (true) {
// Increment i
i++;
}
If I set a breakpoint on the line with the comment, I could keep using the command continue to go through one iteration of the loop and go back to that line. However, if I wanted to skip over 10 iterations (i.e. use the command continue 10 times), how would I do that?
lldb tends to use options where gdb would use a command argument. That makes it easier to have a bunch of different ways to condition a particular command without having to come up with ad hoc mini-syntaxes for each command.
Anyway, so in lldb you would do:
(lldb) c -i 10
You can see this in help:
(lldb) help continue
Continue execution of all threads in the current process.
Syntax: continue <cmd-options>
Command Options Usage:
continue [-i <unsigned-integer>]
-i <unsigned-integer> ( --ignore-count <unsigned-integer> )
Ignore <N> crossings of the breakpoint (if it exists) for the currently selected thread.
'continue' is an abbreviation for 'process continue'
Note also that you can do the same thing just by setting the ignore count in the breakpoint you just hit: break modify -i 10 <BKPTNO>.
Just add a conditional breakpoint. In gdb it's like this
break ... if cond
Set a breakpoint with condition cond; evaluate the expression cond each time the breakpoint is reached, and stop only if the value is nonzero--that is, if cond evaluates as true. `...' stands for one of the possible arguments described above (or no argument) specifying where to break. See section Break conditions, for more information on breakpoint conditions.
https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_28.html
For example if i is currently 0 and you want to break on line 10 then use
break 10 if i >= 10
Just increase the condition value based no the current value of i
I don't know lldb but according the the mapping list break foo if strcmp(y,"hello") == 0 in gdb can be done as the following in lldb
(lldb) breakpoint set --name foo --condition '(int)strcmp(y,"hello") == 0'
(lldb) br s -n foo -c '(int)strcmp(y,"hello") == 0'
If there's no loop counter you can just declare a debug variable yourself
expr unsigned int $foo = 1
breakpoint set --name foo --condition '++$foo >= 10'
As part of a Compiler Principles course I'm taking in my university, we're writing a compiler that's implemented in OCaml, which compiles Scheme code into CISC-like assembly (which is just C macros).
the basic operation of the compiler is such:
Read a *.scm file and convert it to an OCaml string.
Parse the string and perform various analyses.
Run a code generator on the AST output from the semantic analyzer, that outputs text into a *.c file.
Compile that file with GCC and run it in the terminal.
Well, all is good and well, except for this: I'm trying to read an input file, that's around 4000 lines long, and is basically one huge expressions that's a mix of Scheme if & and.
I'm executing the compiler via utop. When I try to read the input file, I immediately get a stack overflow error message. It is my initial guess that the file is just to large for OCaml to handle, but I wasn't able to find any documentation that would support this theory.
Any suggestions?
The maximum string length is given by Sys.max_string_length. For a 32-bit system, it's quite short: 16777211. For a 64-bit system, it's 144115188075855863.
Unless you're using a 32-bit system, and your 4000-line file is over 16MB, I don't think you're hitting the string length limit.
A stack overflow is not what you'd expect to see when a string is too long.
It's more likely that you have infinite recursion, or possibly just a very deeply nested computation.
Well, it turns out that the limitation was the amount of maximum ram the OCaml is configured to use.
I ran the following command in the terminal in order to increase the quota:
export OCAMLRUNPARAM="l=5555555555"
This worked like a charm - I managed to read and compile the input file almost instantaneously.
For reference purposes, this is the code that reads the file:
let file_to_string input_file =
let in_channel = open_in input_file in
let rec run () =
try
let ch = input_char in_channel in ch :: (run ())
with End_of_file ->
( close_in in_channel;
[] )
in list_to_string (run ());;
where list_to_string is:
let list_to_string s =
let rec loop s n =
match s with
| [] -> String.make n '?'
| car :: cdr ->
let result = loop cdr (n + 1) in
String.set result n car;
result
in
loop s 0;;
funny thing is - I wrote file_to_string in tail recursion. This prevented the stack overflow, but for some reason went into an infinite loop. Oh, well...
I would like to change my stack size to allow a project with many non-tail-recursive functions to run on larger data. To do so, I tried to set OCAMLRUNPARAM="l=xxx" for varying values of xxx (in the range 0 through 10G), but it did not have any effect. Is setting OCAMLRUNPARAM even the right approach?
In case it is relevant: The project I am interested in is built using OCamlMakefile, target native-code.
Here is a minimal example where simply a large list is created without tail recursion. To quickly check whether the setting of OCAMLRUNPARAM has an effect, I compiled the program stacktest.ml:
let rec create l =
match l with
| 0 -> []
| _ -> "00"::(create (l-1))
let l = create (int_of_string (Sys.argv.(1)))
let _ = print_endline("List of size " ^ string_of_int (List.length l) ^ " created.")
using the command
ocamlbuild stacktest.native
and found out roughly at which length of the list a stack overflow occurs by (more or less) binary search with the following bash script foo.sh:
#!/bin/bash
export OCAMLRUNPARAM="l=$1"
increment=1000000
length=1
while [[ $increment > 0 ]] ; do
while [[ $(./stacktest.native $length) ]]; do
length=$(($length+$increment))
done
length=$(($length-$increment))
increment=$(($increment/2))
length=$(($length+$increment))
done
length=$(($length-$increment))
echo "Largest list without overflow: $length"
echo $OCAMLRUNPARAM
The results vary between runs of this script (and the intermediate results are not even consistent within one run, but let's ignore that for now), but they are similar no matter whether I call
bash foo.sh 1
or
bash foo.sh 1G
i.e. whether the stack size is set to 1 or 2^30 words.
Changing the stack limit via OCAMLRUNPARAM works only for bytecode executables, that are run by the OCaml interpreter. A native program is handled by an operating system and executed directly on CPU. Thus, in order to change the stack limit, you need to use facilities, provided by your operating system.
For example, on Linux there is the ulimit command that handles many process parameters, including the stack limit. Add the following to your script
ulimit -s $1
And you will see that the result is changing.
LLDB print context around current line every time like this:
int a = 12;
int b = a * 13;
-> printf("%d\n", b);
return 0;
}
In the same time, GDB just print one current line:
-> printf("%d\n", b);
Can I make GDB print context every step like LLDB? Googling give all around list command.
a way to accomplish this might be by defining a macro that redefines a keyword, such as 's' or 'n'.
for example, if you wanted to print out the value of the stack pointer at each step you could redefine 's' by entering these lines into the (gbd) console:
def s
step
info registers sp
end
now every time you use the command 's' you actually do a step and print of the sp register
There is no built-in way to do this.
You could maybe make it work, sort of, using hookpost-stop to invoke an explicit list command.
I think most people just use one of the many gdb GUIs instead, though.