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

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

Related

Some exported symbols disappear after creating a dynamic framework with the ios_framework rule

I am facing quite a strange situation trying to build a mixed-language dynamic iOS framework with Bazel.
The source code of the framework consists of *.c, *.cpp, *.m, *.mm, *.h, *.hpp files.
My first naive attempt was to declare a single objc_library rule referencing all the sources. That failed with an error message reading something about conflicting rules. Then I declared four distinct objc_library rules for *.m, *.mm, *.c, and *.cpp files respectively, and then referenced all these four rules as dependencies for the final ios_framework rule.
At this point, everything compiled and linked just fine (barring several compiler warnings which were expected). However, now the black magic begins:
The static library resulting from compiling ObjectiveC++ sources does contain all the necessary symbols (verified with the "nm" tool)
The .apple_binary_lipobin file resulting from the linking phase does not contain symbols from ObjectiveC++ sources
I believe I carefully went through the command lines used for compiling and linking, both for Bazel and xcodebuild.
The only anomalies I was able to spot:
xcodebuild passes a -single_module argument when linking, while Bazel cross tool does not.
Bazel cross tool adds '-stdlib=libc++' '-std=gnu++11' command line arguments when invoking wrapped_clang_pp during linking, while xcodebuild does not pass these arguments. I guess Bazel does this because there're these lines in the default Apple CROSSTOOL:
action_config {
config_name: "objc++-executable"
action_name: "objc++-executable"
tool {
tool_path: "wrapped_clang_pp"
execution_requirement: "requires-darwin"
}
flag_set {
flag_group {
flag: "-stdlib=libc++"
flag: "-std=gnu++11"
}
but I am not sure if these flags are really needed when invoking the linker.
I must admit I've run out of ideas except for trying to patch the CROSSTOOl file to make it behave as close as xcodebuild as possible.
Please help.
Can you try adding alwayslink = 1 to the objc_library target containing the C++ symbols? The linker is deadstripping the C++ symbols as they are not being referenced anywhere in the binary.

How to create a call graph of an iOS app?

I'm looking for a relatively simple way of creating a call graph of an iOS app (or a framework), using it's Xcode project or the obj code it emits.
The project files are a combination of Objective C, Swift and C++.
I've already tried clang's scan-build, but haven't had any luck turning the .dot files into graphViz graphs. I ended up with hundreds of .dot files and after dot, for over an hour, tries to load them up, nothing happens.
I've also tried to use opt, by adding this to my build line:
-S -emit-llvm -o - | opt -dot-callgraph -S
(from this SO question
but I get only a 107 byte callgraph.dot file and that doesn't have anything notable in it.
I think these errors are what make the output useless:
clang-5.0: warning: 'linker' input unused [-Wunused-command-line-argument]
clang-5.0: warning: argument unused during compilation: '-emit-llvm' [-Wunused-command-line-argument]

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

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.

Cant' build OpenCV 3.2.0 (Mingw32)

I know... Another one of this... But no one else's error is the same as mine and I've been trying to build opencv with mingw32 for days now.
When building OpenCV with mingw the command mingw32-make fails at some point trying to compile sources\modules\ts\src\ts_gtest.cpp with error pic bellow:
I've tried following several tutorials, but none work cleanly and this is the best I could get stuff to work.
What I did:
Installed Mingw and added C:\Mingw\bin\ to PATH environment variable.
Installed CMake and added it too to PATH.
Extracted OpenCV to C:\ and created forlder C:\opencv\mingwBuild\
In CMake-GUI I define source folder as C:\opencv\sources\ and build folder as C:\opencv\mingwBuild\.
Hit Configure and select Mingw Makefiles, with 'Use default native compilers' (have also specified compilers explicitly and the result is the same.).
Hit Generate, which creates the Makefile.
I open C:\Mingw\msys\1.0\msys.bat to have a console with all variables loaded (have also tried directly from a simple cmd.exe, given that PATH is set for mingw, but I get the same error in compilation). Navigate to C:\opencv\mingwBuild\ and run mingw32-make.
And that's where the error shows up after a while. Any ideas?
Turns ou gTest was not compiling in Mingw for some reason.
As I don't intend to test my code (for now) I removed opencv_ts from instalation (by deselecting it in Cmake, after configuring and before generating).
Someone mentions, in the first link #Dan Masek refers, that GTest has this issue with type conversion under mingw. They say that you can edit ts_gtest.cpp to apply the correct conversion, according to error message. That may be a solution if you need this module.
Another comment in #Dan Masek's second link mentions that gcc's version 5 surpasses the issue, which version 4 has. So, getting a hold of such distro may also be a solution.
For me it seems to be fixed by applying this fix: https://github.com/msk-repo01/opencv/commit/9a1835ce6676836ce278d723da4ff55a8f900ff1
(Also see: https://github.com/opencv/opencv/issues/8105)
The fix basically replaces the "_RTL_CRITICAL_SECTION" by "_CRITICAL_SECTION" for MingW compilers in modules/ts/include/opencv2/ts/ts_gtest.h in the following way:
The lines
// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.
// This assumption is verified by
// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.
struct _RTL_CRITICAL_SECTION;
(around line 723 in OpenCV 3.2.0 release from Dec. 2016) are replaced by
# if GTEST_OS_WINDOWS_MINGW
// MinGW defined _CRITICAL_SECTION and _RTL_CRITICAL_SECTION as two
// separate (equivalent) structs, instead of using typedef
typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# else
// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION.
// This assumption is verified by
// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION.
typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
# endif
and
_RTL_CRITICAL_SECTION* critical_section_;
is replaced by
GTEST_CRITICAL_SECTION* critical_section_;

Undefined symbol on xcode with custom library for ios (definition of the symbol is there)

I know there are other questions with that same title, but none of them have the same problem than me.
I have two projects. One of them builds a library, the other one builds an app that uses that library.
When I build the library it's all ok. It creates a .a file which contains the library. When I try to build the second project, I get the following message:
Undefined symbols for architecture armv7:
"_SPLite3_rtree_geometry_callback", referenced from:
_register_spatialite_sql_functions in liblibspatialite.a(spatialite.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Thats bad. At first I did not know what it was talking about, but after some research, found that the library may have not be built for armv7, so I used the lipo command to check the architecture:
lipo -info liblibspatialite.a
This produces the following output.
Non-fat file: liblibspatialite.a is architecture: armv7
Ok so the architecture is right. Then what? Maybe check for the symbols of the .o files that will conform the library. For that I used the nm command:
nm spatialite.o | grep SPLite3_rt
Which produces the following output:
U _SPLite3_rtree_geometry_callback
I checked the manpage for nm and saw that the U before the symbol means it's undefined. So it seems that's it. The symbol appears as undefined. I have another version of the project in another workspace. I've checked, and it produces a working library. The nm command returns the following on that other version:
0000e5f6 T _SPLite3_rtree_geometry_callback
0018c668 S _SPLite3_rtree_geometry_callback.eh
So, with this library it's working and it's fine. I've tried to find differences in the build options of both projects but they look the same to me.
I can build with the first version of the library if I include the source files of the library in the compiler section of the properties of the project. (Select target -> Build phases -> Compile sources), but I think that's not the point of using a library.
So, I'd like to know what can I do so that the _SPLite3_rtree_geometry_callback gets included in the library.
Thanks in advance.
EDIT:
Some more info. In spatialite.c, there is the following code:
#define sqlite3_rtree_geometry_callback SPLite3_rtree_geometry_callback
SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry *, int nCoord, double *aCoord, int *pRes),
void *pContext
);
EDIT 2:
Code for the method:
/*
** Register a new geometry function for use with the r-tree MATCH operator.
*/
SQLITE_API int sqlite3_rtree_geometry_callback(
sqlite3 *db,
const char *zGeom,
int (*xGeom)(sqlite3_rtree_geometry *, int, double *, int *),
void *pContext
){
RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */
/* Allocate and populate the context object. */
pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
if( !pGeomCtx ) return SQLITE_NOMEM;
pGeomCtx->xGeom = xGeom;
pGeomCtx->pContext = pContext;
/* Create the new user-function. Register a destructor function to delete
** the context object when it is no longer required. */
return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY,
(void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
);
}
Check that spacialite.c is added to the library's target.
You have to specify SQLITE_ENABLE_RTREE in preproccessor macro
Ok. This seems weird but it looks like I finally fixed it. Everything is correctly defined, so why it is not working I don't know.
I was using the xcode target preferences to define the preprocessor macros. Instead of that, I changed the SQLITE_ENABLE_RTREE to the .pch file, and after that the build contains the missing symbol.

Resources