GDB/LLDB break at all functions of specified module/shared library - ios

In lldb, I got help breakpoint set:
-a <address-expression> ( --address <address-expression> )
Set the breakpoint at the specified address. If the address maps uniquely to a particular binary, then the address will be converted to a "file" address, so that the
breakpoint will track that binary+offset no matter where the binary eventually loads. Alternately, if you also specify the module - with the -s option - then the
address will be treated as a file address in that module, and resolved accordingly. Again, this will allow lldb to track that offset on subsequent reloads. The
module need not have been loaded at the time you specify this breakpoint, and will get resolved when the module is loaded.
and
-r <regular-expression> ( --func-regex <regular-expression> )
Set the breakpoint by function name, evaluating a regular-expression to find the function name(s).
and
-s <shlib-name> ( --shlib <shlib-name> )
Set the breakpoint only in this shared library. Can repeat this option multiple times to specify multiple shared libraries.
Now I want to set breakpoints at every function of specified module/dylib that you can find in the results of command image list -f.
Take libobjc.A.dylib and MyOwn.dylib as examples. I tried following commands but failed:
(lldb) breakpoint set -r libobjc.A.dylib
Breakpoint 1: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
(lldb) b +[ThunderManager load]
Breakpoint 2: where = MyOwn.dylib`+[ThunderManager load] +16 at ThunderManager.m:20, address = 0x000000010489f274
(lldb) breakpoint set -r MyOwn.dylib`*
Breakpoint 3: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
I want lldb get break at all functions of module libobjc.A.dylib or MyOwn.dylib, or any other specified loaded module/shared library. How to set the breakpoints in lldb?

(lldb) break set -r . -s libobjc.A.dylib
The -s option takes a shared library as its value, and that limits the breakpoint to the specified shared library. You can specify the -s option more than once to specify more than one shared library for inclusion in the breakpoint search.
The -r option's value is a regular expression; if the symbol name matches that expression, it will be included in the breakpoint. . matches everything.
The lldb tutorial:
http://lldb.llvm.org/tutorial.html
starts with a description of the structure of lldb commands that you might find helpful.

Related

How to make Google Closure Compiler understand the `caches` variable (CacheStorage)?

If I use caches in my service worker code then Google Closure Compiler (launched with the advanced optimizations mode) will tell me :
/var/www/html/perso/otraSite/web/js/sw_viaTypescript.js:79: ERROR - [JSC_UNDEFINED_VARIABLE] > variable caches is undeclared
})(caches);
^^^^^^
1 error(s), 0 warning(s)
A workaround that I use until now is ... I put window.caches so Google Closure Compiler succeeds to compile but if I let that code, browsers will tell me :
sw.js:18 Uncaught ReferenceError: window is not defined
So I replace window.caches by caches in the code compiled by Google Closure Compiler afterwards but ... having to do this every single time is pretty annoying.
Is there a cleaner way to handle it?

How to open file for writing?

I'm trying to open and write to a file using Dart's IO library.
I have this code:
File file = File("text.txt");
RandomAccessFile raf = file.openSync();
raf.writeStringSync("A string!");
Now when doing this I get the following error in the console:
(OS Error: Access is denied., errno = 5)
So file is not opened for writing, and I'm looking here: open method, and can't figure out how to use open or openSync to get RandomAccessFile I can write to.
It says I need to use write constant to do that but just can't figure out how?
If I try to create FileMode and add it to open method as an argument I get an error saying:
Error: Too many positional arguments: 0 allowed, but 1 found.
So open and openSync methods can't take any arguments, how would one use FileMode, and open method to open a file that is ready for writing? So I need to get RandomAccessFile that is in writing mode? And by default its only in read mode? I'm not trying to use writeString or writeStringSync, I know those methods exist, but I'm interested in how is this done using open and openSync methods that return RandomAccessFile!
Update:
You are getting this error:
Error: Too many positional arguments: 0 allowed, but 1 found.
because the openSync method has no positional arguments, but just one named parameter (mode).
So to fix your code you must add it:
RandomAccessFile raf = file.openSync(mode: FileMode.append); //Or whatever mode you'd to apply
Having said that, there are several other ways to write to a file, most of them listed in the docs:
writeString or writeStringSync, I'd suggest these if what you need is just to write once to a file.
openWrite, which returns a Stream that can be written in order to write to the file.
(All of these methods have a FileMode mode named parameter)

Why can't I set a breakpoint in my library?

the goal is to debug a method deep within a library.
We can debug c functions in that same library (as long as they are not in the .m files), but apparently no Objective-C code, or even c code within any .m file.
When I try to set breakpoints manually, (break set -n), I get:
WARNING: Unable to resolve breakpoint to any actual locations.
The code does get called, the trusty logger confirms that.
My hunch is that debugging information gets lost somewhere along the way: We are building a static library, then another static library ("Framework" style), and finally we are linking this into our app. Yes, that's complicated but, historical reasons, you know.
I have tried to examine the first .a file to see what is going on, but when I try to load it into lldb I have to create a target. And target creation fails for either architecture:
target create -d --arch i386 libFoo.a
error: 'libFoo.a' doesn't contain the architecture i386
target create -d --arch armv7 libFoo.a
error: 'libFoo.a' doesn't contain any 'remote-ios' platform architectures: arm64, armv7, armv7f, armv7k, armv7s, armv7m, armv7em, armv6m, armv6, armv5, armv4, arm, thumbv7, thumbv7k, thumbv7s, thumbv7f, thumbv7m, thumbv7em, thumbv6m, thumbv6, thumbv5, thumbv4t, thumb
lipo -info libFoo.a
Architectures in the fat file: libFoo.a are: armv7 i386
Does anyone have a good idea how to best tackle this issue? The code is definitely linked, working, but lldb can not set breakpoints.
Thanks a lot
Addendum:
I have created the most simple setup I could think of, and I see very, very odd results:
If I try to lookup certain things, some will return a file and a line number, others will not:
image lookup -s Foo::faz()
1 symbols match 'Foo::faz()' in […]/Build/Products/Debug-iphoneos/Test.app/Test:
Address: Test[0x00010334] (Test.__TEXT.__text + 22060)
Summary: Test'Foo::faz() at Foo.cpp:858
image lookup -s FazBar
1 symbols match 'FazBar' in […]/Build/Products/Debug-iphoneos/Test.app/Test:
Address: Test[0x00038eb4] (Test.__TEXT.__text + 188844)
Summary: Test'FazBar
Trying to set breakpoints in the corresponding files yields, well, expected results:
(lldb) break set -f Foo.cpp -l 877
Breakpoint 5: where = Test'Foo::faz() + 76 at Foo.cpp:877, address = 0x000cb380
(lldb) break set -f bar.c -l 585
Breakpoint 6: no locations (pending).
WARNING: Unable to resolve breakpoint to any actual locations.
How can I dig into the .a file to see why certain files are not found?
Well, someone (actually not me, had the absolutely bright idea of setting
GCC_GENERATE_DEBUGGING_SYMBOLS = NO
somewhere hidden deep.
Setting it to yes, well, you guessed it, solves the issue
Alex
set exception break point like above
go to brekpoint navigation click on + and slecte add exception brak point
Try using DYLD_BIND_AT_LOAD environment variable set. This should disable lazy binding, which often fails to hit symbolic breaküpints

How can I find the address of a stack trace in LLDB for iOS

When I get a crash report, the offending part of my code will sometimes look like this, instead of showing me the actual line number, even though the crash report is symbolicated:
-[ViewController myMethod:] + 47
In order to debug this, I need to know what line of my code this represents so that I can visually inspect it, set a breakpoint, etc.
What is a good way to get the address of a method plus offset, as shown above, using LLDB?
NOTE: this question is NOT a duplicate of how to read a crash report. I know how to read a crash report. I am asking very specifically how to get the corresponding line using LLDB. Nothing in the other answers shows how to do that. They are quite verbose and go into all kinds of things about dealing with crash reports and debugging in general, but don't show what the specific steps on LLDB are. Please do not duplicate this bug.
[note this ONLY works if you save Archives in XCode of all the builds you released]
Information you need to collect first:
APPNAME: the short name of your app as seen in the Archive directory (typically the XCode Target name; you will see it immediately when you look at the Archive directory in Finder below).
CRASHING_FUNCTION_NAME: name of function shown in useless Apple backtrace (in the OP's example, -[ViewController myMethod:])
ARCH: architecture of device that crashed. Most likely the right value is either armv7 or arm64. If you don't know, try both.
Ok here are the steps:
In XCode go to Window...Organizer...Archives
Right-click on the Archive for the release the crashing user has, and choose Show in Finder
open a Terminal shell and cd to that directory shown in Finder
execute the following in the shell:
lldb -arch ARCH Products/Applications/APPNAME.app/APPNAME
inside lldb do the following:
(lldb) add-dsym dSYMs/APPNAME.app.dSYM/Contents/Resources/DWARF/APPNAME
(lldb) disassemble --name CRASHING_FUNCTION_NAME
you now see a rich disassembly with symbols, and lo and behold, each line shows the same decimal offset as the original useless Apple backtrace (in the OPs example, the useless offset was 47), as in:
APPNAME[0xf4a7c] <+47>: ldr r0, [r0, r1]
you might be able to figure out the corresponding source line just from this information, if the disassembly has enough symbols to help you figure out where you are.
if not, there is another great trick. Pass the address of the line that crashed:
(lldb) image lookup -v --address 0xf4a7c
Now lldb shows you a rich collection of information---much richer than what is shown by Apple stack backtraces even when they do contain line numbers, and much richer than lldb source list---about all the source lines that contributed to the assembler instruction at that address. Pay close attention to both the Summary and LineEntry sections. Example:
Address: APPNAME[0x000f4a7c] (APPNAME.__TEXT.__text + 963740)
Summary: APPNAME`myclass::myfunc(bool, bool) + 904 [inlined] std::__1::deque<mystruct, std::__1::allocator<mystruct> >::operator[](unsigned long) + 22 at myfile.cpp:37945
APPNAME`myclass::myfunc(bool, bool) + 882 [inlined] myinlinefunc(int) + 14 at myfile.cpp:65498
APPNAME`myclass::myfunc(bool, bool) + 868 at myfile.cpp:65498
Module: file = "/Users/myuser/mydir/arch/Products/Applications/APPNAME.app/APPNAME", arch = "armv7"
CompileUnit: id = {0x000483a4}, file = "/Users/myuser/mydir/myfile.cpp", language = "objective-c++"
Function: id = {0x0045edde}, name = "myfunc", range = [0x000f46f4-0x000f572a)
FuncType: id = {0x0045edde}, decl = myfile.cpp:65291, compiler_type = "void (_Bool, _Bool)"
Blocks: id = {0x0045edde}, range = [0x000f46f4-0x000f572a)
id = {0x0045f7d8}, ranges = [0x000f4936-0x000f51c0)[0x000f544c-0x000f5566)[0x000f5570-0x000f5698)
id = {0x0046044c}, ranges = [0x000f49c6-0x000f49ce)[0x000f49d6-0x000f49d8)[0x000f4a2e-0x000f4a38)[0x000f4a58-0x000f4a82), name = "myinlinefunc", decl = myfile.cpp:37938, mangled = _Z11myinlinefunci, demangled = myinlinefunc(int)
id = {0x00460460}, ranges = [0x000f4a58-0x000f4a64)[0x000f4a66-0x000f4a82), name = "operator[]", decl = deque:1675, mangled = _ZNSt3__15dequeI12mystructNS_9allocatorIS1_EEEixEm, demangled = std::__1::deque<mystruct, std::__1::allocator<mystruct> >::operator[](unsigned long)
LineEntry: [0x000f4a7c-0x000f4a82): /Applications/Xcode7.3.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/deque:1678:14
Symbol: id = {0x00000805}, range = [0x000f46f4-0x000f572a), name="myclass::myfunc(bool, bool)", mangled="_ZN7myclass7myfuncEbb"
Variable: id = {0x00460459}, name = "myvar1", type = "int", location = , decl = myfile.cpp:37938
Variable: id = {0x0045f7dd}, name = "myvar2", type = "bool", location = , decl = myfile.cpp:65583
Variable: id = {0x0045edf2}, name = "this", type = "myclass *", location = [sp+56], decl =
Variable: id = {0x0045ee01}, name = "myvar3", type = "bool", location = , decl = myfile.cpp:65291
Variable: id = {0x0045ee0e}, name = "myvar4", type = "bool", location = , decl = myfile.cpp:65292
In this example under Summary, we can see that the line that crashed was actually a combination of code from myclass::myfunc(), myinlinefunc() and std::deque::operator[]. This kind of mashing together is very common for optimized code. This is often enough information to find the offending source line of your code. Under LineEntry we see the line number for the most-nested code contributing to that assembler line, which in this case is in the STL std::deque code, but in other cases might be the exact line number you want in your code.
Now the only remaining question is: why on earth doesn't Apple just do this for us in the original backtrace? They clearly have all this information themselves! Why do they make us jump through such hoops? What are they hiding?
Your steps (image lookup + p/x addr + offset) will give you the raw address, as you found. But the original crash report probably included an address before the method + offset --- it is just as easy to slide your binary to the correct address using target modules load. At the end of the crash report there should be a list of the binary images present in the program, including load address and UUID.
But more importantly, while the address is nice what you're really after is the source location. In that case, once you've determined the correct address for the method (or slid it to the matching address via target modules load), you can use source list
(lldb) so l -a `addr + offset`
I'm using the backtick notation here which does an in-line expression evaluation. There's a handy shortcut for most commands that take an address: if you omit spaces, you can write the expression without backticks:
(lldb) so l -a addr+offset
You can also use image lookup with an address. If you have debug information, this will tell you what the current location of variables are at this point. Why is this useful? Because most crash reports include the register context at crash and so any variables that are currently in a register are provided to you (-v is necessary to get all of the register location information).
(lldb) im loo -v -a addr+offset
Finally -- this isn't going to work because you're dealing with an Objective-C method name -- but with a simple C function name you can do the offset arithmetic in-line as long as you cast the function name to a pointer type (it's not legal C to add an offset to a function pointer). e.g.
(lldb) so l -a (char*)main+10
Here is something I found that worked:
First you need to find the address of the method itself.
image lookup -v -F "-[ViewController myMethod:]"
in the result you will see a lot of info, but the range part will give you want you want
... range = [0x000708c0-0x00070c6c) ...
(where 0x000708c0 is address of method)
Now to add the given offset of 47, just use LLDB to do that math for you:
(lldb) p/x 0x000708c0 + 47
(int) $0 = 0x000708ef
and you get your answer, the offending line is on 0x000708ef
Or better yet, based on Jason Molenda's answer, is to just go straight to the code listing, which will show the line number:
(lldb) source list -a `0x000708c0 + 47`
EDIT: improved based on the answer from Jason Molenda

Vim: How do I tell where a function is defined? (

I just installed macvim yesterday and I installed vim latex today.
One of the menu items is calling a broken function (TeX-Suite -> view).
When I click on the menu-time it makes this call:
:silent! call Tex_ViewLatex()
Question: Where can I find that function? Is there some way to figure out where it is defined?
Just for curiosity sake I removed the silent part and ran this:
:call Tex_ViewLatex()
Which produces:
Error detected while processing function Tex_ViewLaTeX:
line 34:
E121: Undefined variable: s:viewer
E116: Invalid arguments for function strlen(s:viewer)
E15: Invalid expression: strlen(s:viewer)
line 39:
E121: Undefined variable: appOpt
E15: Invalid expression: 'open '.appOpt.s:viewer.' $*.'.s:target
line 79:
E121: Undefined variable: execString
E116: Invalid arguments for function substitute(execString, '\V$*', mainfname, 'g'
)
E15: Invalid expression: substitute(execString, '\V$*', mainfname, 'g')
line 80:
E121: Undefined variable: execString
E116: Invalid arguments for function Tex_Debug
line 82:
E121: Undefined variable: execString
E15: Invalid expression: 'silent! !'.execString
Press ENTER or type command to continue
I suspect that if I could see the source function I could figure out what inputs are bad or what it is looking for.
Use the :verbose prefix command:
:verbose function Tex_ViewLaTeX
In the second line of output (just above the function's body) is the location of where the function was defined.
I installed gVim 7.2 on windows and latex-suite, and miktex too
I tried what you said, after compile and view, I can view the dvi files
The error message seemed like to indicate it's the view's problem
The document for latex-suite said the viewer for Macintosh is not set, maybe it's where the problem lies
I think you can try to set a few variables in your .vimrc file, to set up the proper viewing app for PDF files
And the source code for Tex_ViewLaTeX is here:
http://www.tedpavlic.com/research_related/tpavlic_masters_thesis/compiler.vim
By the way, I also installed MacVim on my Macbook Pro, however I never used vim for LaTeXing, because I find TextMate and its latex bundle is much superior than MacVim, you'll definately like it
One way to search would be to do a grep or vimgrep on directory tree where you thought the source file was located. Search for 'function Tex_ViewLatex' or 'function! Tex_ViewLatex'.
I believe in the usual install it would be in a .../ftplugin/latex-suite/compiler.vim file, as part of the latex-suite plugin. There are a couple ftplugin directories, so make sure you get right one (one is in tree of main vim install and other may be off your home .vim directory.
It seems there is a bug with the Tex_ViewLatex function on OS X. Check here for some info:
http://comments.gmane.org/gmane.comp.editors.vim.latex.devel/775
Put this in your .vimrc, solved the problem for me.
let g:Tex_ViewRule_pdf = 'open -a Preview.app'

Resources