How to use Instruments Time Profiler with Executable - c++

I'm trying to use Mac Instruments Time Profiler to optimize my code for building a MandelBox. I found how to make my executable my target process, but when the program runs, it gives me an error in the Console window saying it cannot find the .txt file associated with the program.
Do I need to tell the profiler where to look to find the file? The text file is already in the same directory as the executable. Any thoughts? Thanks.

This problem is not unique to Instruments. The same thing would presumably happen if your current working directory was something other than the location of your program. For example, if you were to do cd / ; /path/to/yourprogram.
You either need to make your program find its own location and then find its text file as a sibling in the containing directory or take the path of the text file as an argument. Or, you will always have to set the working directory to your program's location before invoking it.
That last approach is an immediate workaround for the problem with Instruments. On the panel where you choose the target executable, you can also configure various parameters, such as arguments, environment variables, and the working directory. Set the working directory to the directory that contains the text file and it should work.

Related

Getting CURRENT path to own executable (C++)

Everything on StackOverflow says to use a bunch of different methods to get the full path to your executable. The PROBLEM is that NONE of these methods get the path to your executable. They get the path to where your executable WAS when it was executed. If you run the executable and then move it, the path that you get is ALWAYS the path you ran it from. How can I get the path to where it actually is?
GetFileInformationByHandleEx with option FileNameInfo returns the current path, sans the drive designator, on the current device, when the running executable is moved within that device. To use this you apparently need to have opened the file for reading at program start up (before it's moved). To get the executable's path at startup you can use GetModuleFileName.

LLDB - setting source code path

According to the official guideline of lldb, the ability to view source code during debug session (using the command source list) is done by setting new pathname for source files.
i.e. if i compiled my project in /tmp on one computer and deployed it on another computer where the source code reside in /Users/Src/ , i should type settings set target.source-map /tmp /Users/Src from running lldb in the deployment machine.
However, what happens if i got the executable from someone else, and don't know the build directory. and maybe the source-code is organized differently from where is was built (but the file contents is the same).
my questions are :
Does lldb know how to search for matching source file recursively in the supplied path ?
How can I get the original pathname form the mach-o executable ?
here's the formal description of the command :
Remap source file pathnames for the debug session. If your source files are no longer located in the same location as when the program was built --- maybe the program was built on a different computer --- you need to tell the debugger how to find the sources at their local file path instead of the build system's file path.
If you know a function name in the code in question, do:
(lldb) image lookup -vn <FunctionName> <BinaryImageNameContainingFunction>
and look for the CompileUnit entry. The path given there is the path lldb got from the debug information.

Reading the command a program was called from

If this has already been answered elsewhere, I'm sorry, I couldn't find it.
I have an interesting problem whereby I have a compiled program, prog.exe, which reads a file prog.cfg which contains the config. If I open prog.exe by double-clicking on it, everything's good. However, if I open it from a command line or batch file, I first have to set the directory. For example, if I have my program in a progs folder on the desktop, and from the desktop run progs\prog.exe, it doesn't load the config because it's looking for the config on the desktop ie in the current working directory.
This is fine if you know about it, but it's just another hoop for users to jump through. Is there a way in c++ to backtrack to the command used to launch the program to deduce whether the config file will be in the current working directory or not?
Alternatively, am I asking completely the wrong question?
Many thanks!
You can use GetModuleFileName(nullptr, buf, bufsize) to get a path to the executable.
Note that the standard main function's argv[0] is not guaranteed to provide that path, and when it provides a path, is not guaranteed to provide a programmatically usable representation of the path.
if i understand you correctly, you always want your .exe read your .cfg file from the folder your .exe located? right?
try argv[0].
argv[0] is your full .exe path when you run your exe, and it is a parameter of main function.

C++ How should I send project that reads specific .txt files?

I have a c++ project that I would like to send to someone in executable form. The issue is the program must read from a .txt that I created (specific deliminators). Currently my program reads from a file path that is specific to my computer,
parseFile("/Users/David/Desktop/FinalProject/Store.txt");
How could I package the .txt file and the executable file together, where the exec. reads specifically from the that .txt on anyone's machine?
Note: I am using Xcode
Change your programs to receive 'file path' as a parameter. Write a note(ReadMe) with the program to specify the file format and added a sample data file with the package
tl;dr: if you just put the text file in the same folder with your executable, you can open it with parseFile("Store.txt");
In most runtime implementations, there is a notion of a "working directory." When you open up an executable via the graphical shell (by double clicking it or something to that effect) the working directory is the same as the directory the executable is in.
Now, if you try to open a file in your program via a path that isn't fully qualified, then the path that gets used will be relative to the working directory.
A fully qualified path is a discrete path that points to a single entity in your filesystem. "/Users/David/Desktop/FinalProject/Store.txt" is one such example, as it starts at root (/ on *nix, DriveLetter:\ on Windows) and says exactly which directories you need to traverse to get to your file.
A path that is not fully qualified (which basically means that it doesn't start at the root of your filesystem) can be used to perform relative file addressing. Most runtimes will assume that any path that is not fully qualified is meant to be relative to the working directory, which basically means that the path that actually gets opened is the result of concatenating your provided path to the end of the working directory.
As an example, if you opened your binary, which is stored as /Users/David/Desktop/FinalProject/a.exe, then the working directory would be set to /Users/David/Desktop/FinalProject/. If your program then tried to open "Store.txt", the runtime would see that you're trying to open a path that isn't fully qualified, so it would assume you meant to open a file relative to the working directory, which would then be /Users/David/Desktop/FinalProject/ + Store.txt, which would be /Users/David/Desktop/FinalProject/Store.txt.
The nice thing about this is that if you move your binary, the working directory moves too. if you move a.exe along with Store.txt to /Users/David/Desktop/FinalProject(copy)/, then when you open /Users/David/Desktop/FinalProject(copy)/a.exe, the working directory will be /Users/David/Desktop/FinalProject(copy)/ now, and now when you call parseFile("Store.txt"), it will instead open up /Users/David/Desktop/FinalProject(copy)/Store.txt. This holds true when moving to other computers, too.
It's worth noting that if your binary is run from a command line utility, the working directory will often be the directory the command line shell is in, rather than the executable's directory. It is, however, a part of the C standard that the first command line parameter to main() should be the name of the executable, and most implementations supply you with the fully qualified path. With some minimal parsing, you can use that to determine what path to use as a base for addressing files.

std::ifstream::open() not working

I am developing a prototype for a game, and certain gameplay rules are to be defined in an ini file so that the game designers can tweak the game parameters without requiring help from me in addition to a re-compile. This is what I'm doing currently:
std::ifstream stream;
stream.open("rules.ini");
if (!stream.is_open())
{
throw new std::exception("Rule file could not be opened");
}
// read file contents here
stream.close();
However, my stream never opens succesfully. Diving deep into the STL source during debugging reveals that _getstream() (as defined in stream.c) keeps on returning NULL, but I just can't figure out why this is. Help, anyone?
Edit: Rules.ini is in the same directory as the .exe file.
You are assuming that the working directory is the directory that your executable resides in. That is a bad assumption.
Your executable can be run from any working directory, so it's usually a bad idea to hard-code relative paths in your software.
If you want to be able to access files relative to the location of your executable, you should first determine the path of your executable and create a fully qualified path from that.
You can get the name of your executable by examining the argv[0] parameter passed to main(). Alternatively, if you're on Windows, you can get it with GetModuleFileName() by passing NULL as the first parameter.
Is the scope of your open stream correct.
"rules.ini" isn't a full path so it has to be relative so what is it relative to. Or do you need to use full path there.
(wild assumption here) you are using visual studio. During debug, your program is going to search the project directory for "rules.ini"
However, if you try executing your program from "myproject/debug/myexe.exe", it should run fine because it is going to search "/debug" for rules.ini
Like its been mentionned you should specify the full path because relative path tend to lead to errors