Relative path in Xcode generated DWARF file - swift

When I compile my swift framework MyFramework I makes so that Xcode produces MyFramework.framework (the compiled framework) and MyFramework.framework.dSYM (the dSYM file).
By running dwarfdump myframework.framework.dSYM/Contents/Resources/DWARF/MyFramework I've noticed that all the paths to the source files are absolute paths.
This makes it impossible to share these two artefacts (together with the source code) with my colleagues and allow them to use the compiled framework and being able to debug their code properly. More precisely they are not able to step-in inside the framework with the debugger.
For this reason they need recompile the framework which is very inconvenient.
Is there a way to modify the DWARF to edit these paths or even better to convince Xcode to use relative path in the DWARF file?

While I'm not aware of a way to change the paths stored in the dSYM or to make them relative, I can offer a way to work around the issue and be able to debug with those symbols on an arbitrary machine with source code in a different base path.
Once you find out what the original path is (e.g. /Users/rob/src/Project), and you have the code for that library in e.g. /Users/luka/Sources/Project, then you can issue this lldb command, which will replace for that session of the debugger the original path with your path:
settings set target.source-map /Users/rob/src/Project /Users/luka/Sources/Project
Unfortunately you'll need to run this command for each debugging session. To do that, you can create a breakpoint in your main, which runs that command and continues execution without stopping.
To find the original source path you can either use dwarfdump as you mention, or you can look up a symbol you know is in that binary from lldb with im loo -v -n MySymbol or through other parameters of the command (depending on the type of symbol you're trying to use).

Related

from where CopySwiftLibs gets executes and copies standard swift libraries? is there a way to avoid it?

From where CopySwiftLibs gets executed? I am trying to avoid getting libswift*.dylib which gets copied through CopySwiftLibs, I see an option in xcode, which is "Always Embed Swift Standard Libraries", but it is set to "No", but still libswift libraries gets copied to Contents/Frameworks/ of app. Is there a way yo avoid it?
CopySwiftLibs phase calls swift-stdlib-tool. You can learn about its usage with this Terminal command:
xcrun swift-stdlib-tool --help
There’s an option called --source-libraries <path> that defines where to copy the libraries from. Apparently, to prevent it from copying any libraries you can set that path to some empty or non-existent folder.
You can define custom OTHER_SWIFT_STDLIB_TOOL_FLAGS build setting for your target and set it to
--source-libraries /dev/null

CoqIDE error with exporting modules in the same library

I am running CoqIDE to use read the textbook series "Software Foundations", I am currently reading the volume "Logical Foundations". I just started Chapter 2 (Induction), but when I try to run the line
From LF Require Import Basics.
I get an error statement
The file ...\LF\Basics.vo contains library
Basics and not library LF.Basics
I tried renaming the directory the file was located in, and recompiled the buffers, but neither of these actions helped. What Shoudl i do in order to solve this problem?
We've been improving the explanation in the soon-to-be-released new version of LF. Here is the relevant bit:
For the [Require Export] to work, Coq needs to be able to
find a compiled version of [Basics.v], called [Basics.vo], in a directory
associated with the prefix [LF]. This file is analogous to the [.class]
files compiled from [.java] source files and the [.o] files compiled from
[.c] files.
First create a file named [_CoqProject] containing the following line
(if you obtained the whole volume "Logical Foundations" as a single
archive, a [_CoqProject] should already exist and you can skip this step):
[-Q . LF]
This maps the current directory ("[.]", which contains [Basics.v],
[Induction.v], etc.) to the prefix (or "logical directory") "[LF]".
PG and CoqIDE read [_CoqProject] automatically, so they know to where to
look for the file [Basics.vo] corresponding to the library [LF.Basics].
Once [_CoqProject] is thus created, there are various ways to build
[Basics.vo]:
- In Proof General: The compilation can be made to happen automatically
when you submit the [Require] line above to PG, by setting the emacs
variable [coq-compile-before-require] to [t].
- In CoqIDE: Open [Basics.v]; then, in the "Compile" menu, click
on "Compile Buffer".
- From the command line: Generate a [Makefile] using the [coq_makefile]
utility, that comes installed with Coq (if you obtained the whole
volume as a single archive, a [Makefile] should already exist
and you can skip this step):
[coq_makefile -f _CoqProject *.v -o Makefile]
Note: You should rerun that command whenever you add or remove Coq files
to the directory.
Then you can compile [Basics.v] by running [make] with the corresponding
[.vo] file as a target:
[make Basics.vo]
All files in the directory can be compiled by giving no arguments:
[make]
Under the hood, [make] uses the Coq compiler, [coqc]. You can also
run [coqc] directly:
[coqc -Q . LF Basics.v]
But [make] also calculates dependencies between source files to compile
them in the right order, so [make] should generally be prefered over
explicit [coqc].
If you have trouble (e.g., if you get complaints about missing
identifiers later in the file), it may be because the "load path"
for Coq is not set up correctly. The [Print LoadPath.] command
may be helpful in sorting out such issues.
In particular, if you see a message like
[Compiled library Foo makes inconsistent assumptions over
library Bar]
check whether you have multiple installations of Coq on your machine.
It may be that commands (like [coqc]) that you execute in a terminal
window are getting a different version of Coq than commands executed by
Proof General or CoqIDE.
- Another common reason is that the library [Bar] was modified and
recompiled without also recompiling [Foo] which depends on it. Recompile
[Foo], or everything if too many files are affected. (Using the third
solution above: [make clean; make].)
One more tip for CoqIDE users: If you see messages like [Error:
Unable to locate library Basics], a likely reason is
inconsistencies between compiling things _within CoqIDE_ vs _using
[coqc] from the command line_. This typically happens when there
are two incompatible versions of [coqc] installed on your
system (one associated with CoqIDE, and one associated with [coqc]
from the terminal). The workaround for this situation is
compiling using CoqIDE only (i.e. choosing "make" from the menu),
and avoiding using [coqc] directly at all. *)

In Adacore's GPR file, how can I set the compiler include search paths for C++

I have some C++ code that I need to compile using Adacore GNAT Programming Studio.
One file (SomeHeader.h) is in a Common directory (../../Common/) relative to my GPR file.
Our convention for C++ include directives is to use
#include "Common/SomeHeader.h"
No matter what I do, I cannot get GprBuild to find "Common/SomeHeader.h"
I followed the instructions here at AdaGem 108 with modifications for C++
for Include_Switches ("c++") use ("-I ../../");
and
for Include_Path ("c++") use "../..";
None of this seems to work for me during gprbuild and frustratingly I can't seem to get at the backend command that gprbuild is using even after turning the build verbosity up.
I see some temp files in the build messages but they get deleted before I can access them.
I am using Adacore GPS 17.1 on Windows 10 i686-pc-mingw32, GNAT Pro 17.1.
Does anyone know how to get include search paths working in Adacore's Gprbuild?
If you want to use relative paths, and you are dead set on using the -I flag, be aware that the current directory at the time you compile your c++ code it is set to the obj directory configured for grp.
So if the directory you want to include is located at C:\Foo\Bar\src\include\ and your grp obj directory is at C:\Foo\Bar\env\gpr\obj then your relative path will need to use -I..\..\..\src\include
I haven't tried to use gprbuild for compiling C++ source text yet, but I suppose it works more or less like with Ada, where you add the relevant directories to the Source_Dirs attribute:
project Cookie is
for Languages use ("C++");
for Source_Dirs use (".",
"../..");
[...]
end Cookie;

SQLAPI++: Get path to shared library loaded by executable

SQLAPI++ has an unusual feature where you set a string to tell it where to find the ODBC shared library. In my case this is libtdsodbc.so, and my application actually links that library at build time, but at runtime this is not enough for SQLAPI++ to work.
My code is:
SAConnection conn;
conn.setOption("ODBC.LIBS") = "libtdsodbc.so";
conn.Connect("SERVER=...", "", "", SA_ODBC_Client);
ODBC.LIBS is documented like this:
Forces SQLAPI++ Library to use specified ODBC manager library.
The above code works if you set LD_LIBRARY_PATH to a directory containing libtdsodbc.so. But if you don't, Connect() fails:
libtdsodbc.so: cannot open shared object file: No such file or directory
DBMS API Library 'libtdsodbc.so' loading fails
This library is a part of DBMS client installation, not SQLAPI++
Make sure DBMS client is installed and
this required library is available for dynamic loading
Linux/Unix:
1) The directories in the user's LD_LIBRARY_PATH environment variable
2) The list of libraries cached in /etc/ld.so.cache
3) /usr/lib, followed by /lib
It works again if you set ODBC.LIBS to a full path rather than just a filename. But how can the application know which path?
My application (outside of SQLAPI++) finds libtdsodbc.so via its RUNPATH which is set at build time. This path is not a system path like /usr/lib. I'd like to have SQLAPI++ use the same library which is loaded in the application at runtime.
One idea is for the application to inspect its own RUNPATH, search for libtdsobc.so, and use that path. But this requires quite a bit of fiddly code to basically reimplement what ld.so already does.
I don't want to bake the path into the executable at build time separately from RUNPATH, because I sometimes edit RUNPATH before deployment (and then I'd need to edit two things).
Ideally I would like to tell SQLAPI++ to just use the library which is already loaded. I can figure this path out by running lsof -p PID | grep libtdsodbc.so but running shell commands from within the executable is not a good solution (and again I would rather not reimplement lsof).
You could either use dl_iterate_phdr (the link also includes a sample code which prints out lib names) or manually parse /proc/self/maps.

Missing symbol names when profiling IPhone application with Instruments

I am compiling an IPhone application via command line (so no XCode options involved) and I am unable to get my symbol names to show when profiling with Instruments. I have tried several flags such as -gdawrf-2 and -g without any success. I have also tried using dsymutils to generate a .dSYM file but i have no clue how I'm supposed to use it so that failed aswell.
Any help will be greatly appreciated!
I Changed my project settings to not include the dSYM file while building:
Changing it to include the dSYM File helped the profiler desymbolize the symbols and fixed my issue:
I was still having issues with this.
My issue was I was able to see the dSYM file being generated, but Instruments wasn't picking it up.
To fix this, do the following:
Locate your dSYM file (should be in ~/Library/Developer/DerivedData/APP_NAME-XXXXXXX/Build/Products/[BUILD_TYPE]-[DEVICE-TYPE]/
With Instruments stopped, click on File -> Re-Symbolicate Document
Scroll down to the entry with your app name
Click "Locate" and choose the folder from step 1
Click the Start button to begin profiling
How Instruments obtains debug information:
Instruments obtains debug info from a .dSYM file which is normally generated automatically by XCode when setting Debug Information Format to DWARF with dSYM File combined with a checkmark in the Generate Debug Symbols option box. Setting these options will add an extra step to the XCode build process and generate a dSYM file after the application has been compiled. Every dSYM is built with a UUID that corresponds to a UUID in a Mach-O section in the binary that it's derived from. A Spotlight importer indexes the UUIDs of every dSym file that is in a Spotlight-accessible location on your Mac. Therefore SPOTLIGHT does all the black magic and is responsible of making the link between the .app you are running and its corresponding .dSYM file.
How to generate debug information and dSYM file without XCode:
Make sure you are compilig with –gdwarf-2 and -g flags. (Other flag combinations might work)
-g
Produce debugging information in
the operating system's native format
(stabs, COFF , XCOFF , or DWARF 2).
GDB can work with this debugging
information. On most systems that use
stabs format, -g enables use of extra
debugging information that only GDB
can use; this extra information makes
debugging work better in GDB but will
probably make other debuggers crash or
refuse to read the program. If you
want to control for certain whether to
generate the extra information, use
-gstabs+, -gstabs, -gxcoff+, -gxcoff, or -gvms (see below). GCC allows
you to use -g with -O. The shortcuts
taken by optimized code may
occasionally produce surprising
results: some variables you declared
may not exist at all; flow of control
may briefly move where you did not
expect it; some statements may not be
executed because they compute
constant results or their values were
already at hand; some statements may
execute in different places because
they were moved out of loops.
Nevertheless it proves possible to
debug optimized output. This makes it
reasonable to use the optimizer for
programs that might have bugs.
-gdwarf-2
Produce debugging information in DWARF version 2 format
(if that is supported). This is the
format used by DBX on IRIX 6. With
this option, GCC uses features of
DWARF version 3 when they are useful;
version 3 is upward compatible with
version 2, but may still cause
problems for older debuggers.
Generate a dSYM file using dsymutil. If the tool isn't recognized in command line, use spotlight to find it.
IMPORTANT: Place .app file on your mac HD before you generate the dSYM if you are working on a networked drive.
dsymutil MyApp.app/MyApp -o
MyApp.app.dSYM
Place the .dSYM file on the mac's local drive and run Instruments as you normally would.
Resettig spotlight's indexing:
If symbols aren't shown, it might be because spotligh is bugged. You can try reseting spotlight's indexing by adding your folder containing the dSYM file (or even your drive) to the “Prevent spotlight from searching these locations” in the spotlight preferences and then removing it right away.
In Xcode 4.5 you can choose to Profile from Debug or Release builds. Release defaults to stripping the symbols when copied to the device. It's very easy to switch to the Debug configuration for profiling without breaking your release configuration. To do that, select Product -> Edit Scheme from the XCode menu. Select "Profile" from the list of schemes that comes up, and then select the correct Build Configuration for that.
Or you could make a separate release/profile configuration and use that in your Profile section of your scheme. How to add a separate build configuration is described in the XCode User Guide.
With Xcode 6 Instruments you can provide dSYM file as follow:
File -> Symbols... menu (when profiling is stopped)
select your app and press Locate button
select path which contains dSYM (usually ~/Library/Developer/DerivedData/APP_NAME-XXXXXXX/Build/Products/[BUILD_CONFIGURATION]-[TARGET_PLATFORM]/). Tip: You can copy this path from terminal and use OS X shortcut ⌘+SHIFT+G in dialog.
Also Instruments will ask you if it should use selected path to try load dSYM for this app in the future. Answer Yes :)
Spent three days trying to figure this out for Xcode 7.1/7.3...
Changing the deployment target to the latest version (9.3 at the time) fixed this issue for me. My company targets 7.0 so I will probably have to create a custom Scheme for profiling the code in Instruments to avoid having to change the target (or forgetting to change the target) when we do a production release.
Seems like it's probably a bug if dSYMs fail to work based on the deployment target?
The problem is that spotlight cannot find the .dSYM files.
This is because Apple changed the location of the DerivedData folder.
The DerivedData now goes in ~/Library
Spotlight will not index ~/Library and as far as I have been able to establish, cannot be made to index it either (e.g. mdimport is ignored).
A work around to get symbols in your profiler, is to simply copy the data outside ~/Library e.g. your home directory will do fine.
I used this command line:
$ cp -r ~/Library/Developer/Xcode/DerivedData/AppName-xxxxxxxxxxx/Build/Products/Release-iphoneos/ ~/
When you kill your profiler, and start a new profile run, you will see that the symbols are available again.
Check the build log and make sure that your -g switch is getting through to the compiler - it's easy to get this wrong when changing settings at the project and/or target levels for different build configurations etc.
Another work around in the version of Instruments that comes with Xcode 4 is to use the Re-Symbolicate Document menu item under the File menu for Instruments. This menu item to allows you to use the symbols located in the .dSYM file in ~/Library/... directory.
In my experience, this is usually because "Profile" has been called before the most recently modified version of the app has been installed on the target device.
Try running the app on the device/target, then calling "Profile" again after it has been reinstalled.
I got this problem because the XCode project was on a network share where Spotlight wouldn't find the dSYM files. Make sure it's on the local drive.