How to get gdb on Linux to find source file for binary cross compiled on windows - linux

I am trying to debug an application that is cross-compiled on a Windows host for a Linux target.
The problem:
Because the initial compilation is in windows the stored source file paths in the binary is of the form C:\Users\foo\project\.... On the Linux target I have put the source files under \home\foo\project\.... By default gdb does not find the source file because of the different path.
What I have tried so far:
Use "directory" command in gdb to give an exact path for the .c source file in the target Linux system where the app is being debugged. This works but unfortunately there are literally hundreds of files so this solution is unrealistic.
Use the set substitute-path C:\\Users\\foo\\project /home/foo/project command to have gdb substitute all prefixes. Note that the \\ seems necessary such that show substitute-path registers the right string. This unfortunately does not work. My guess is that the substitute-path command does not handle ms-dos style paths.
Tried separating the debug info out into a separate .debug file (see How to generate gcc debug symbol outside the build target?) and then using debugedit to change the paths with the command debugedit --base-dir=C:\Users\foo --dest-dir=/home/foo project.debug. Unfortunately this does not work either. debugedit seems to work fine if the existing path is all UNIX/Linux like but doesn't seem to work with ms-dos style paths.
I have looked around stackoverflow and while there are similar topics I can't find anything that will help me. Would really appreciate any suggestions/help. I realize that cross compiling from Windows is a very roundabout way but can't avoid that for the moment.
Thanks

Although it's rather old question, I did encountered the same problem. I managed to resolve it but using sed on binary executable... (yeah, a 'bit' hack-ish, but did not found another way). With sed I've managed to replace symbols paths right inside the executable, the trick is that new path's length should be the same as the old one.
sed -i "s#C:/srcpath#/srcpath/.#g" ./executable
Be sure to make new path the same length, otherwise the executable will brake.

I also have this same problem. Your option 1 isn't as bad as you think because you can script creating all the 'directory' commands with something like this python code:
def get_directory_paths():
return_array = list()
unix_path = os.path.join('my','unix','path')
for root, dirs, files in os.walk(unix_path):
for dir in dirs:
full_unix_path = os.path.join(root,dir)
escaped_unix_path = re.sub("\s", "\\\\ ", full_unix_path)
return_array.insert(0, "directory " + escaped_unix_path)
return '\n'.join(return_array)
The downside is that if you have two source files with the same name in different directories, I don't think gcc can pick the right one. That worries me, but in my particular situation, I think I'm safe.
For option 2 (which I suspect would fix the aliasing condition from #1), I think the problem is that the substitutions are not ending with a "file separator" according to the linux so they aren't applied:
To avoid unexpected substitution results, a rule is applied only if the from part of the directory name ends at a directory separator. For instance, a rule substituting /usr/source into /mnt/cross will be applied to /usr/source/foo-1.0 but not to /usr/sourceware/foo-2.0. And because the substitution is applied only at the beginning of the directory name, this rule will not be applied to /root/usr/source/baz.c either." (from https://sourceware.org/gdb/current/onlinedocs/gdb/Source-Path.html#index-set-substitute_002dpath )
I haven't tried anything like your #3 and I also considered something like #dragn suggestion, but in my situation the paths are not even close to the same length, so that will be an issue.
I think I'm stuck with #1 and a script, but if anyone has other suggestions, I'm interested options :-)

Related

Locating files starting with a string for my hw

I have a conundrum and I am not necessarily trying to cheat or anything I am just simply stuck. I am trying to complete an assignment for my intro to Linux class and I was hoping someone would be able to help me find the right solution. I have to:
In the same directory (where the last file was found) list all files
starting with "host" --
Use the long listing format Use a command to
find the file that shows the name of your computer
now the directory in question is /etc and I have tried several commands to no avail for both of these but especially the first one. I have tried find and locate and even attempted a grep and it just is not working as intended. I can't get files that start with "host" at most I keep getting a list of permission denied or files that end in .host and so I am not sure what I am doing wrong but I really need help so I can turn in my assignment. You don't have to tell me what the exact command should be I am just looking for some guidance again I am not trying to cheat just need help to figure it out.
and welcome to Stack Overflow! Here are some pointers.
See globbing in Linux and the * symbol.
"long listing" is an option for ls command, see ls --help. The name of your computer (or, more accurately, the name of your host) is a file in /etc/. You should see it when doing #1.

Path variable: Find folder path of specific file

On Linux and other Unix-likes, how do I find the path to a specific file that I can use because of the PATH environment variable? For example, if I can use, from the command line:
ls # technically the file name is "ls.exe"
is there a way I can find the path of the ls.exe file explicitly without looking through the PATH variable myself (i.e. maybe have a program search through it but not look myself)?
I understand there are many pitfalls/caveats of doing this, for example a PATH can be a file or even part of a file (I think), plus symlinks, etc. could make it unreliable, but I'm looking for general use cases.
The reason I am asking is I have Windows with msysgit so I have A LOT of folders in my path, and searching every one would be annoying & time-consuming, not to mention harder because of Windows limitations, but I can still presumably use almost anything Linux can use.
$ type ls.exe
ls.exe is /usr/bin/ls.exe

Android.mk : How to add backslashes automatically

In Android.mk, I read the context of system environment variable like $(MY_ENV_VARIABLE). The env variable contains following string inside "Program(x86) Files".
But the build fails, claiming that the specified library cannot be found. The failure takes place of windows style weird space in "Program(x86) Files".
So my question is, is there any mechanism to automatically escape the special symbols like space (i.e "Program(x86)\ Files", for my case).
You might be able to try using the windows pathing conventions of using the tilde character so instead of C:\Program(x86) Files\mydir it would be C:\PROGRA~2\mydir (PROGRA~1 is for the 64 bit program files).
Like eldar said in the comments it is better to not use spaces in path names because most of make's functions use spaces as delimiters. Another option you could try is to take a look at my suggestion here: WINAVR not finding file in include path with whitespace
Since Android is a pretty complicated build environment it might be hard to see where to place the final substitution unless you know what you're doing and hopefully won't break anything else in the makefile.

Find: Parameter format not correct

I keep hearing this is a path issue with cygwin. It is prevent emacs from working within my cygwin. When I execute find on the cli (not bash/cygwin) I get the same error not matter what I type. I've read this is a problem with path creation within cygwin and that it should be prepending itself to the path. As you can see it is doing that.
Here is my /etc/profile
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
export PATH
Problem is that as everyone else stated, emacs is using find.exe provided by windows. To change this, you need to change your %userprofile%.emacs file.
As nobody else states (even faq!), this file is not created automatically anymore. Go into Options > Save options the mini-buffer (one line at the bottom of emacs) will tell you where the file is being written to.
Go in there and add this line (You've installed cygwin at c:\cygwin, right?):
(setq find-program "C:\\cygwin\\bin\\find.exe")
You may need to restart Emacs for this to take effect.
Just add this line to you .profile
alias find='/cygdrive/c/cygwin/bin/find.exe'
Oddly-enough, I needed to use
(setq find-program "/bin/find.exe")
instead.
But thanks for the suggestion Drew.
Adding a setq find-program [msys2 or git path] in my init file, as suggested (I tried different forms), didn't work for me. "C:\Windows\System32\find.exe" is first in the path if I type where find in eshell and I didn't find how to remove it, only how to add others, which doesn't solve the problem.
So I share here the more radical, but working (also in Powershell), solution I used: replacing the find.exe in "C:\Windows\System32" with the one from "C:\msys64\usr\bin". I kept the old file in case, but so far so good. You need to change the permissions for this operation (see here how to gain full control, but I suggest only applying this to the file, not the whole folder, and putting things back after ;)).

How to convert a makefile into readable code?

I downloaded a set of source code for a program in a book and I got a makefile.
I am quite new to Linux, and I want to know whether there is any way I can see the actual source code written in C?
Or what exactly am I to do with it?
It sounds like you may not have downloaded the complete source code from the book web site. As mentioned previously, a Makefile is only the instructions for building the source code, and the source code is normally found in additional files with names ending in .c and .h. Perhaps you could look around the book web site for more files to download?
Or, since presumably the book web site is public, let us know which one it is and somebody will be happy to point you in the right direction.
A Makefile does not contain any source itself. It is simply a list of instructions in a special format which specifies what commands should be run, and in what order, to build your program. If you want to see where the source is, your Makefile will likely contain many "filename.c"'s and "filename.h"'s. You can use grep to find all the instances of ".c" and ".h" in the file, which should correspond to the C source and header files in the project. The following command should do the trick:
grep -e '\.[ch]' Makefile
To use the Makefile to build your project, simply typing make should do something reasonable. If that doesn't do what you want, look for unindented lines ending in a colon; these are target names, and represent different arguments you can specify after "make" to build a particular part of your project, or build it in a certain way. For instance, make install, make all, and make debug are common targets.
You probably have GNU Make on your system; much more information on Makefiles can be found here.
It looks like you also need to download the SB-AllSource.zip file. Then use make (with the Makefile that you've already downloaded) to build.

Resources