How I can redirect output of this command :
(gdb) x /a $esp
0x22ff30: 0x403064 <__register_frame_info+4206692>
to make this:
(gdb) x /s 0x00403064
0x403064 <__register_frame_info+4206692>: "\nPress key (q for exit) ? "
(gdb)
I mean something like:
(x /a $esp) | (x /s)
Redirecting the output of a command in GDB is not possible, as far as I know.
There is another way to do this, though:
x /s *(void**)$esp.
This will examine the memory at the address stored at the top of the stack.
Related
How would I go about setting up a hotkey (eg: CTRL+g) to perform a VIMGREP operation on the current visual selection in the current buffer? My intent is to show a line-numbered list in the "quickfix" window of all matching search results.
Right now, if I want to get a list of results for a regex search, I could do a command-mode query like so:
:vimgrep /foo/ %
However, there are two problems with this:
I don't want to have to type out the entire query. I could always do a visual selection, then use CTRL+r, CTRL+w, to paste the current visual selection into the command buffer, but I'd like something simpler than this.
The above approach requires that the current buffer is already saved to a file. I'd like to be able to work on a temporary buffer I've pasted into VIM rather than having to save a file buffer each time I want to do this.
Thank you.
A low-level solution
Try [I and the :ilist command:
[I " lists every occurrence of the word under the cursor
" in the current buffer (and includes)
:ilist /foo<CR> " lists every occurrence of foo in the current buffer
" (and includes)
Press : followed by a line number and <CR> to jump to that line.
You can use them on the visual selection with a simple mapping:
xnoremap <key> "vy:<C-u>ilist /<C-r>v<CR>:
You'll probably need to sanitize the register upon insertion, though.
See :help :ilist.
Another even lower-level solution
Since we are at it, let's dig even deeper and find the amazingly simple and elegant:
:g/foo/#
that you could use in the same way as :ilist above:
xnoremap <key> "vy:<C-u>g/<C-r>v/#<CR>:
Limitations
The solutions above don't use the quickfix window, obviously, but they allow you to:
see their result as a list,
use line numbers to actually get to where you want.
They have limitations, though:
the list is not cached so you must perform the search again if you want to get to a different occurrence,
the list is not transient like the quickfix list so you can't use navigation commands like :cnext or :clast to move around the result.
A higher-level solution
If those limitations are a showstopper, the function below, adapted from justinmk's answer in this /r/vim thread, gives you an almost complete solution:
press [I in normal mode to search for the word under the cursor in the whole buffer,
press ]I in normal mode to search for the word under the cursor after the current line,
press [I in visual mode to search for the selected text in the whole buffer,
press ]I in visual mode to search for the selected text after the current line.
The function below uses the quickfix list/window when the buffer is associated to a file and falls back to the regular behavior of [I and ]I otherwise. It could probably be modified to be used as part of an :Ilist command.
" Show ]I and [I results in the quickfix window.
" See :help include-search.
function! Ilist_qf(selection, start_at_cursor)
" there's a file associated with this buffer
if len(expand('%')) > 0
" we are working with visually selected text
if a:selection
" we build a clean search pattern from the visual selection
let old_reg = #v
normal! gv"vy
let search_pattern = substitute(escape(#v, '\/.*$^~[]'), '\\n', '\\n', 'g')
let #v = old_reg
" and we redirect the output of our command for later use
redir => output
silent! execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern
redir END
" we are working with the word under the cursor
else
" we redirect the output of our command for later use
redir => output
silent! execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
redir END
endif
let lines = split(output, '\n')
" better safe than sorry
if lines[0] =~ '^Error detected'
echomsg 'Could not find "' . (a:selection ? search_pattern : expand("<cword>")) . '".'
return
endif
" we retrieve the filename
let [filename, line_info] = [lines[0], lines[1:-1]]
" we turn the :ilist output into a quickfix dictionary
let qf_entries = map(line_info, "{
\ 'filename': filename,
\ 'lnum': split(v:val)[1],
\ 'text': getline(split(v:val)[1])
\ }")
call setqflist(qf_entries)
" and we finally open the quickfix window if there's something to show
cwindow
" there's no file associated with this buffer
else
" we are working with visually selected text
if a:selection
" we build a clean search pattern from the visual selection
let old_reg = #v
normal! gv"vy
let search_pattern = substitute(escape(#v, '\/.*$^~[]'), '\\n', '\\n', 'g')
let #v = old_reg
" and we try to perform the search
try
execute (a:start_at_cursor ? '+,$' : '') . 'ilist /' . search_pattern . '<CR>:'
catch
echomsg 'Could not find "' . search_pattern . '".'
return
endtry
" we are working with the word under the cursor
else
" we try to perform the search
try
execute 'normal! ' . (a:start_at_cursor ? ']' : '[') . "I"
catch
echomsg 'Could not find "' . expand("<cword>") . '".'
return
endtry
endif
endif
endfunction
nnoremap <silent> [I :call Ilist_qf(0, 0)<CR>
nnoremap <silent> ]I :call Ilist_qf(0, 1)<CR>
xnoremap <silent> [I :<C-u>call Ilist_qf(1, 0)<CR>
xnoremap <silent> ]I :<C-u>call Ilist_qf(1, 1)<CR>
NB: <C-r><C-w> inserts the word under the cursor, not the visual selection for which there's unfortunately no such shortcut. We have no choice but to yank.
Grepping a scratch buffer
You can use the :global command combined with :caddexpr to add entries to the current quickfix list. Here is the example from :h :caddexpr:
:g/mypattern/caddexpr expand("%") . ":" . line(".") . ":" . getline(".")
There are a few issues with this:
This approach only does one match per line
Does not start a new quickfix list
Really long to type out
Assumes the default global 'errorformat' hasn't been changed
To overcome these issues (all but the multiple matches per line) put the following command in your ~/.vimrc file:
command! -nargs=1 -bar Cgrep
\ let s:errorformat = &errorformat |
\ try |
\ let &errorformat='%f:%l:%m' |
\ cexpr [] |
\ execute 'g'.<q-args>.'caddexpr expand("%").":".line(".").":".getline(".")' |
\ cc |
\ finally |
\ let &errorformat = s:errorformat |
\ endtry
Now you can use :Cgrep/foo/ to grep the current buffer.
A visual mapping
To make it so you can do a visual version of this you need to yank in the selected text and pass it to our :Cgrep command via <c-r>. Here is an example visual mapping g/ to do just that:
xnoremap g/ y:<c-u>Cgrep/<c-r>"/<cr>
There are some issues with this mapping too:
This clobber the unnamed register, #"
This assumes the visually selected text will be a valid pattern
The following mapping fixes the mapping by using the expression register via <c-r>= and very no magic, \V:
xnoremap g/ :<c-u>let #/=#"<cr>gvy:let [#/,#"]=[#",#/]<cr>Cgrep/\V<cr>=substitute(escape(#/,'/\'),'\n','\\n','g')<cr>/<cr>
Conclusion
Personally I would forgo the mapping and get a visual star plugin (there are few out there). There is a nice Vimcast about this: Search for the selected text. I would then use that with the :Cgrep command we just created via :Cgrep// or better yet xmap g/ *:Cgrep//<cr>
For more help see:
:h :caddexpr
:h :cexpr
:h :g
:h 'efm
:h registers
:h /\V
To search for the visual selected text in files *.c via the hotkey CTRL+g do:
:vmap <silent> <unique> <c-g> y:vimgrep "<c-r>"" *.c<CR>
Two problems remain:
You want to search in a buffer, not in a file.
You want line numbers in the quickfix.
To 1:
As far as I know vimgrep can only search in files. The solution would be to write the buffer in a temporary file and search in this file and delete the temporary file when it is no longer needed. This solution requires a script which is called via the hotkey.
Just a hint: To get a suitable filename the VIM function tempname() can be used. Example:
let s:tmpfile = tempname()
(Sorry, I currently have no time to show a script solution here, maybe I add one later. Maybe somebody else has a better solution or can provide a script?)
To 2:
This command will enable line number in the current buffer:
:set number
Is it possible to set a complex breakpoint which has condition which involves check on the argument passed to the outer function(frame).
eg.
1 #0 sample::_processMessage (this=0xa5c8c0, data=0x7fffe5ae31db "\027w\270߸\023\032\212\v", line=0x7fffe4799db8 "224.4.2.197:60200", should_process=true) a sample.cpp:426
2 #1 0x00007ffff682f05d in sample::_process (this=0xa5c8c0, should_process=true, line=0x7fffe4799db8 "224.4.2.197:60200", data=0x7fffe5ae31db "\027w\270߸\023\032\212\v", sn=31824) a sample.cpp:390
3 #2 0x00007ffff6836744 in sample::drain (this=0xa5c8c0, force=true) at sample.cpp:2284
4 #3 0x00007ffff682ed81 in sample::process (this=0xa5c8c0, mdData=0x7fffe67914e0) at sample.cpp:354
Here I want to set a break point on sample.cpp:356,which is on in the function process-frame#3,
if the _process or frame #1 at the time hitting breakpoint has sn == 31824
so actually break point is at function _process but I want pause the execution in the function process
Thanks in advance
I don't know if it's possible to create conditional breakpoints that reference an outer frame, but you could use breakpoint commands to achieve a similar result.
Here's an example gdb session:
(gdb) break some-location
(gdb) commands
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>silent
>up
>if (sn != 31824)
>continue
>end
>end
Now every time gdb hits the breakpoint it will automatically move up a frame, check sn and continue if the value is not correct. This will not be any (or much) slower than a conditional breakpoint, and the only real downside is that it will print out a line each time the breakpoint is hit, even if gdb then continues.
The silent in the command list cuts down on some of the normal output that is produced when a breakpoint is hit, this can be removed to get a more verbose experience.
This can be accomplished with a gdb convenience function implemented in python:
import gdb
class CallerVar(gdb.Function):
"""Return the value of a calling function's variable.
Usage: $_caller_var (NAME [, NUMBER-OF-FRAMES [, DEFAULT-VALUE]])
Arguments:
NAME: The name of the variable.
NUMBER-OF-FRAMES: How many stack frames to traverse back from the currently
selected frame to compare with.
The default is 1.
DEFAULT-VALUE: Return value if the variable can't be found.
The default is 0.
Returns:
The value of the variable in the specified frame, DEFAULT-VALUE if the
variable can't be found."""
def __init__(self):
super(CallerVar, self).__init__("_caller_var")
def invoke(self, name, nframes=1, defvalue=0):
if nframes < 0:
raise ValueError("nframes must be >= 0")
frame = gdb.selected_frame()
while nframes > 0:
frame = frame.older()
if frame is None:
return defvalue
nframes = nframes - 1
try:
return frame.read_var(name.string())
except:
return defvalue
CallerVar()
It can be used like:
(gdb) b sample.cpp:356 if $_caller_var("sn",2)==31824
Ok so I am working on a project and I am doing this and I get to the if statement in confirmOne and it gives me "( was not expected at this time." Please help!
Many of the stray "You got to here!" messages are from me trying to debug it. I really need this soon. Please help. I also tried deleting parts and it still doesn't seem to work. If you see any other errors please tell me as I need all the help I can get. Thank you!
:grabInput
echo Please enter the username of the user you wish to access.
REM - } End Echoing Information/Main Menu | Grab Input {
set /p result=
goto correctName
REM - } End Grab Input | Process Input {
:correctName
set /p input=%result%
goto confirmOne
:confirmOne
echo Got to confirmOne
pause
if %input%==[] (
pause
cls
echo Oops! Looks like you didn't enter anything! Try Agian!
echo.
echo ................................................................................
echo.
goto grabInput
) ELSE (
goto confirmTwo
)
:confirmTwo
echo Got to ConfirmTwo
pause
if %input%==~help (
goto helpMenu
) ELSE (
goto confirmThree
)
:confirmThree
echo Got to ConfirmThree
if %input%==~info (
goto infoMenu
) ELSE (
goto swapDrive
)
Well, if you didn't enter anything for %input%, then your if statement would look like if ==[] (.
Your if statement should look like if [%input%] == [] (
I also see a lot of unnecessary code, you should take a look over your script.
Batch ALWAYS works on strings.
with the statement if %input%==[], when %input% is set to [nothing] (which is what you're trying the detect), batch substitutes [nothing] fo %input% and gets
IF ==[] (
and is confused because '(' is not a comparison operator.
[] is not some magic mantra. It's an old method of detecting the presence of parameters such that [%1] would equal [] if the parameter was absent. It doesn't work when the variable contains spaces or some other characters.
if "%var%"=="" is better
if not defined var is better still
Note that
set /p var=
will NOT set var to [nothing] in you simply press enter, It will leave var unchanged.
Hence this
set var=something
set /p var=
will leave var set to something. You should code this as
set "var="
set /p var="Some prompt "
if not defined var echo VAR is not defined
The quotes around var= ensures that var is NOT set to [some spaces] if there are trailing spaces on the line.
Other than that, the sequence
goto somelabel
:somelabel
(REM lines are irrelevant) is superfluous.
equally, in
if somecondition (goto somewhere) else (goto somewhereelse)
:somewhereelse
the else condition is superfluous
Batch only notices :label as a DESTINATION for a GOTO or a CALL. and will otherwise simply charge straight through any :label it finds as though they were remarks statements.
My short batch file keeps failing. what is wrong with my if?
:user
set /p usercommand = "Input: "
if %usercommand% equ "done"
echo got here!
goto end
else
echo not done
goto user
First - with set /p usercommand = you set variable named usercommand<space>. Remove space after intended name (so it becames set /p usercommand=).
That said, this you will run you into another error as your if else syntax is incorrect. It must be:
if "%usercommand%" equ "done" (
your commands here
) else (
your commands here
)
Please note I quoted %usercommand%. Without that your comparison will never be true (unless of course you require your input to be explicitly quoted)
I'd like to make GDB call a given function a large number of times automatically, say 100. Is there any command that will let me do that?
Save this example script into a file say my_gdb_extensions
define fcall_n_times
set $count = $arg0
set $i=0
while($i < $arg0)
call $arg1
set $i = $i + 1
end
end
You can find more about gdb extensions here.
$ gdb -x my_gdb_extensions <your_bin>
(gdb) start
(gdb) fcall_n_times 10 fact(3)
In the mentioned example 10 is the number of times you want to call the function. fact(3) is the function name with argument as 3.