While I debug with GDB I can print string:
x/s $r0
The output is
IDog123456
I want to change the value so when I print x/s $r0 I will see
ICat45555
I have tried to :
set $r0+1 ={int} 0x43617434 #Cat4
set $r0+5 ={int} 0x35353535 #5555
But it doesn't work , How can I do that without malloc ? only with hex string please?
Generally, the gdb expression parser operates similar to the current language, so, in the above, when you write:
set $r0+1 ={int} 0x43617434 #Cat4
The left hand side is an integer constant, which can't be assigned to.
Instead, you should write this as you would in C:
set *($r0+1) = (int) 0x43617434
Which should do the job.
Sometime, you might end up needing to case the pointer of the LHS too, like this:
set *((int *) ($r0+1)) = (int) 0x43617434
But I suspect in your case you'll be OK.
Related
I saw this code en Tcl:
entry .amount -validate key -validatecommand {
expr {[string is int %P] || [string length %P]==0}
}
I know that it's an entry validation but, what does "%P" in that code? I was looking in the Tcl's doc but I didn't find nothing.
I think this is another way to do it but it has the same symbols:
proc check_the_input_only_allows_digits_only {P} {
expr {[string is int P] || [string length P] == 0}
}
entry .amount \
-validate key \
-validatecommand {check_the_input_only_allows_digits_only %P}
The tcl-tk page for entry says
%P
The value of the entry if the edit is allowed. If you are configuring the entry widget to have a new textvariable, this will be the value of that textvariable.
https://www.tcl.tk/man/tcl8.4/TkCmd/entry.html#M25
I think this is another way to do it but it has the same symbols:
You're close. You just have to use $ in a few places because you're just running a procedure and that's as normal for using parameters to procedures.
proc check_the_input_only_allows_digits_only {P} {
expr {[string is int $P] || [string length $P] == 0}
}
entry .amount \
-validate key \
-validatecommand {check_the_input_only_allows_digits_only %P}
It's recommended that you write things like that using a procedure for anything other than the most trivial of validations (or other callbacks); putting the complexity directly in the callback gets confusing quickly.
I recommend keeping validation loose during the input phase, and only making stuff strictly validated on form submission (or pressing the OK/Apply button, or whatever it is that makes sense in the GUI) precisely because it's really convenient to have invalid states there for a while in many forms while the input is being inputted. Per-key validation therefore probably should be used to only indicate whether it's believed that form submission will work, not to outright stop even transients from existing.
The string is int command returns true for zero-length input precisely because it was originally put in to work with that validation mechanism. It grinds my gears that actual validation of an integer needs string is int -strict. Can't change it now though; it's just a wrong default…
entry .amount -validate key -validatecommand {string is int %P}
I am trying to write a code that calculate the size of a list.
Here is what I've done:
let rec l = function
| [] -> 0
| t::q -> 1 + l q
print_int(l ([1;2;3;4]))
The problem is that it's saying me :
It is applied to too many arguments; maybe you forgot a `;'.
When I put the double semicolon ;; at the end of the definition of l it works well, yet I've read that ;; is not useful at all if you are not coding in the REPL, so here I don't see why it's giving me this error.
The following
print_int(l [1;2;3;4])
is a toplevel expression. Such expression needs to be preceded by ;;:
;; print_int(l [1;2;3;4])
Another option is to make this toplevel expression a binding with
let () = print_int(l [1;2;3;4])
When parsing the code the parser advances until it hits l q. At this point there could be more arguments that should get applied to the function l. So the parser keeps going and the next thing it finds is the value print_int. Another argument to l. Which gives you your error.
The parser has no way of knowing that you had finished the code for the function l. In the top level the special token ;; is used to tell the parser that the input is finished and it should evaluate the code now. After that it starts paring the remaining input again.
Now why doesn't compiled code also have the ';;' token?
Simply because its not needed. In compiled code the line print_int(l [1;2;3;4]) is not valid input. That would be a statement you want to execute and functional languages have no such thing. Instead print_int(l [1;2;3;4]) is an expression that returns a value, () in this case, and you have to tell the compiler what to do with that value. A let () = tells the compiler to match it against (). And the let ... also tells the compiler that the previous let rec l ... has finished. So no special ;; token is needed.
Or think of it this way: In the top level there is an implicit let _ = if your input doesn't start with let. That way you can just type in some expression and see what it evaluates to without having to type let _ = every time. The ';;' token still means "evaluate now" though and is still needed.
This question already has an answer here:
Why does strcmp() in a template function return a different value?
(1 answer)
Closed 2 years ago.
char s1[] = "0";
char s2[] = "9";
printf("%d\n", strcmp(s1, s2)); // Prints -9
printf("%d\n", strcmp("0", "9")); // Prints -1
Why do strcmp returns different values when it receives the same parameters ?
Those values are still legal since strcmp's man page says that the return value of strcmp can be less, greater or equal than 0, but I don't understand why they are different in this example.
I assume you are using GCC when compiling this, I tried it on 4.8.4. The trick here is that GCC understands the semantics of certain standard library functions (strcmp being one of them). In your case, the compiler will completely eliminate the second strcmp call, because it knows that the result of strcmpgiven string constants "0" and "9" will be negative, and a standard compatible value (-1) will be used instead of doing the call. It cannot do the same with the first call, because s1 and s2 might have been changed in memory (imagine an interrupt, or multiple threads, etc.).
You can do an experiment to validate this. Add the const qualifier to the arrays to let GCC know that they cannot be changed:
const char s1[] = "0";
const char s2[] = "9";
printf("%d\n", strcmp(s1, s2)); // Now this will print -1 as well
printf("%d\n", strcmp("0", "9")); // Prints -1
You can also look at the assembler output form the compiler (use the -S flag).
The best way to check however is to use -fno-builtin, which disables this optimization. With this option, your original code will print -9 in both cases
The difference is due to the implementation of strcmp. As long as it conforms to the (<0, 0, >0), it shouldn't matter to the developer. You cannot rely on anything else. For all you know, the source code could be determining it should be negative, and randomly generating a negative number to throw you off.
in my little code example I have random values for the variable testvar%bed when I compile with -O2 optimization.
gfortran -O2 test.F90
edit to make the problem more clear:
So the problem is, that I print testvar%bed, and it shows random junk, that changes on every run (unprintable characters, like �����). It should be printing bed.
This only happens on some systems. On
debian gcc 4.9.1 -- okay
osx gcc 4.9.1 -- okay
ubuntu gcc 4.9.1 -- random values
arch gcc 4.9.2 -- random values
This happens if the function is called two times in the code. If I comment out the second call, everything is okai again.
I can also "kind of fix" this if I put an arbitrary print statement at the end of the function.
edit in reply to #tkoenig
The problem does not occur with only -O1 or without any optimizations. It does occur with -O1 -fgcse but not with only -fgcse. Only using -ffrontend-optimize alone does not rise the error.
What am I missing?
program testbug
implicit none
integer, parameter :: STRLEN = 256
type :: ncVarnames_t
! variables names for the different ice models
character (len=STRLEN) :: surf
character (len=STRLEN) :: x, y
character (len=STRLEN) :: bed
character (len=STRLEN) :: thick
end type ncVarnames_t
type (ncVarnames_t) :: testvar
type (ncVarnames_t) :: testvar2
print *, "hello"
testvar = get_ncVarnames ("test")
testvar2 = get_ncVarnames ("test")
print *, trim(testvar%surf)
print *, trim(testvar%bed)
print *, trim(testvar%bed)
print *, trim(testvar%surf)
contains
type (ncVarnames_t) function get_ncVarnames (model) result (v)
character(len=*), intent(in) :: model
! type (ncVarnames_t) :: v
select case (model)
case ("test")
! test model
v%x = 'x'
v%y = 'y'
v%surf = 'surf'
v%bed = 'bed'
case ("pism")
! pism data
v%x = 'x'
v%y = 'y'
v%surf = 'usurf'
v%bed = 'topg'
case default
print *, "unknown model, please use one of [test pism sico]"
stop
end select
end function get_ncVarnames
end program testbug
Looks like a gfortran/gcc bug, which may need some special circumstances to trigger (which is why not everybody appears to be able to reproduce it).
I have also reproduced this and submitted PR 65504. This is a regression against 4.8, so it should receive special attention. Fixes should also be backported to 4.9.
Workaround (as analzyed in the PR): Use -fno-dse.
People use gdb on and off for debugging,
of course there are lots of other debugging tools
across the varied OSes, with and without GUI and,
maybe other fancy IDE features.
I would like to know what useful gdb scripts you have written and liked.
While, I do not mean a dump of commands in a something.gdb file that you source to pull out a bunch of data, if that made your day, go ahead and talk about it.
Lets think conditional processing, control loops and functions written for more elegant and refined programming to debug and, maybe even for whitebox testing
Things get interesting when you start debugging remote systems (say, over a serial/ethernet interface)
And, what if the target is a multi-processor (and, multithreaded) system
Let me put a simple case as an example...
Say,
A script that traversed serially over entries
to locate a bad entry in a large hash-table
that is implemented on an embedded platform.
That helped me debug a broken hash-table once.
This script, not written by me, pretty prints STL containers, such as vector, map, etc: http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt
Totally awesome.
When debugging an AOLserver SIGSEGV crash, I used the following script to examine the TCL-level call stack from GDB:
define tcl_stack_dump
set $interp = *(Interp*)interp
set $frame = $interp->framePtr
while (0 != (CallFrame *)$frame->callerPtr != 0)
set $i = 0
if 0 != $frame->objv
while ($i < $frame->objc)
if (0 != $frame->objv[$i] && 0 != $frame->objv[$i]->bytes)
printf " %s", (char *)(CallFrame *)$frame->objv[$i]->bytes
end
set $i = $i + 1
end
printf "\n"
end
set $frame = (CallFrame *)$frame->callerPtr
end
end
document tcl_stack_dump
Print a list of TCL procs and arguments currently being called in an
interpreter. Most TCL C API functions beginning with Tcl[^_] will have a
Tcl_Interp parameter. Assumes the `interp' local C variable holds a
Tcl_Interp which is represented internally as an Interp struct.
See:
ptype Interp
ptype CallFrame
ptype Proc
ptype Command
ptype Namespace
ptype Tcl_Obj
end
1. When trying to get some 3rd party closed-source DLLs working with our project under Mono, it was giving meaningless errors. Consequently, I resorted to the scripts from the Mono project.
2. I also had a project that could dump it's own information to stdout for use in GDB, so at a breakpoint, I could run the function, then cut-n-paste its output into GDB.
[Edit]
3. Most of my GCC/G++ use has been a while, but I also recall using a macro to take advantage of the fact that GDB knew the members of some opaque data I had (the library was compiled with debug). That was enormously helpful.
4. And I just found this, too. It dumps a list of objects (from a global "headMeterFix" SLL) that contain, among other things, dynamic arrays of another object type. One of the few times I've used nested loops in a macro:
define showFixes
set $i= headMeterFix
set $n = 0
while ($i != 0)
set $p = $i->resolved_list
set $x = $i->resolved_cnt
set $j = 0
printf "%08x [%d] = {", $i, $x
printf "%3d [%3d] %08x->%08x (D/R): %3d/%-3d - %3d/%-3d {", $n, $i, $x, $i->fix, $i->depend_cnt, dynArySizeDepList($i->depend_list), $i->resolved_cnt, dynArySizeDepList($i->resolved_list)
while ($j < $x)
printf " %08x", $p[$j]
set $j=$j+1
end
printf " }\n"
set $i = $i->next
set $n = $n+1
end
end