Can't find program entry point in a C++ project - c++

I have a C++ project in Ubuntu 12.04. To run the project the make file requires the following files:
1-All the .cpp files
2-All the .h files
3-Three shared libraries.
The project is fully functionall and performs according to the specifications. All the required .cpp files and .h files are available. The problem is that there is no main() function in any of the source files and the program entry point resides in one of the three shared libraries. My job is to find out the program execution pipeline and without having any main file I am not able to do that. I can't run the project in any IDE (i.e: eclipse) because there is no main function available.
Question: Can you please tell me how to find the program entry point?
P.S: I will be glad to provide any kind of information or material you may need to solve my problem.
Edit: The CMakeLists.txt file available here.
Edit 2: The build.sh file available here.

To find enty point look into each shared object with:
nm $library | egrep "T main$"
Library with main() will output something like
090d8ab0 T main
Very usefull way to visualize execution tree is to run:
valgrind --tool=callgrind ./my_executable -arg -arg ....
(you can abort execution early with Ctrl+C)
This will output callgrind.<pid> file. To visualize it run kcachegrind callgrind.<pid>.
You will need valgrind:
sudo apt-get install valgrind
and kcachegrind
sudo apt-get install kcachegrind

Build it with the debug option -g and step into the program with a debugger like gdb (or cgdb or ddd). You'll need any appropriate debug libraries libraries though.
Short of that, play with the code a bit. Try putting printf or cout statements that print internal variables in any functions that look important, and see what the program status is and how frequently they get called. If main is hidden in a library, there's probably another function somewhere that behaves like main for the purposes of the API provided by whatever library has the real main.
What's the API documentation for your libraries? (is this a school project?). It sounds odd to have a hidden main and not say anything about it.

In case you use a build system (CMake, SCons, ...) it is highly possible that the build system is also generating some files, and one of them might be containing the main() method. We use this methodology when we generate the main function in order to instantiate classes for libraries that were specifically selected in CMake-gui.
And again, it is possible that the build system deletes the generated files due to some obscure policy the original developers thought of but didn't tell you. So search through your build system files, see what is actually happening there.
Edit
So, after seeing you CMakeLists.txt:
check ${DIR_EXT}/covis/src/ci.cpp where DIR_EXT is SET( DIR_EXT "../ext/" CACHE PATH "Folder holding external libraries" )
See what's in there and let us know :)
Edit2
After seeing build.sh (execute steps in order):
1.
change
`cmake -D COMPILE_BINARY=ON ..`
to
`cmake -D COMPILE_BINARY=ON -DCMAKE_BUILD_TYPE=Debug ..`
and add the same -DCMAKE_BUILD_TYPE=Debug to the other cmake command too.
This will build your library and executable in debug mode.
2.
Now, in one of the c++ source files you have access to and you are sure will be called (the earlier the function will be calle the better), add:
asm("int $0x03");
This will create a breakpoint in your application.
(If you do not want to use this, see below).
3.
Build your application.
4.
Run it via a debugger in terminal:
gdb ./myapplication <ENTER>
(this will give you a gdb prompt)
(if you did not add the asm breakpoint from above, type in the gdb prompt: break filename.cpp:linenumber or break methodname to add a gdb breakpoint).
run <ENTER>
Now your application should stop in your function when it is executed.
You are still in the gdb prompt, so type:
bt <ENTER>
This will print out the backtrace of your application. Somewhere you should see a main function, together with filename and linenumber.
However, that setnames.sh looks interesting, see if it does not do anything funny :)

Related

How to set up C++ Testmate in VS Code

Ok, n00b question. I have a cpp file. I can build and run it in the terminal. I can build and run it using clang++ in VSCode.
Then I add gtest to it. I can compile in the terminal with g++ -std=c++0x $FILENAME -lgtest -lgtest_main -pthread and then run, and the tests work.
I install the C++ TestMate extension in VSCode. Everything I see on the internet implies it should just work. But my test explorer is empty and I don't see any test indicators in the code window.
I've obviously missed something extremely basic. Please help!
Executables should be placed inside the out or build folder of your workspace. Or one can modify the testMate.cpp.test.executables config.
I'd say, never assume something will "just work".
You'll still have to read the manual and figure out what are the names of config properties. I won't provide exact examples, because even though I've only used this extension for a short time, its name, and therefore full properties path, has already changed, so any example might get obsolete quite fast.
The general idea is: this extension monitors some files/folders, when they change, it assumes those are executables created using either gtest or catch2. The extension tries to run them with standard (for those frameworks) flags to obtain a list of test suites and test cases. If it succeeds, it will parse the output and create a nice list in the side panel. Markers in the code are also dependent on the exactly same parsed output, so if you have one, you have the other as well.
From the above, you need 3 things to make this work:
Provide correct path (or a glob pattern) for finding all test executables (while ignoring all non-test executables) in the extension config. There are different ways to do this, depending on the complexity of your setup, they are all in the documentation though.
Do not modify the output of the test executable. For example, if you happen to print something to stdout/stderr before gtest implementation parses and processes its standard flags, extension will fail to parse the output of ./your_test_binary --gtest-list_tests.
If your test executable needs additional setup to run correctly (env vars, cwd), make sure, that you use the "advanced" configuration for the extension and you configure those properties accordingly.
To troubleshoot #2 and #3 you can turn on debug logging for the extension (again, in the VSCode's config json), this will cause an additional "Output" tab/category to be created, where you can see, which files were considered, which were run, what was the output, and what caused this exact file to be ignored.
This messed with me for a while, I did as Mate059 answered above and it didn't work.
Later on I found out that the reason it didn't work was because I was using a Linux terminal inside windows (enabled from the features section) and I previously had installed the G++ compiler using the linux terminal so the compiler was turning my code into a .out file, for some reason TestMate could not read .out files.
Once I compiled the C++ source file using the powershell terminal it created a .exe file which I then changed the path in the setting.json as Mate059 said and it showed up.
TL;DR
Mate059 gave a great answer, go into settings.json inside your .vscode folder and modify "testMate.cpp.test.executables": "filename.exe".
For me it also worked using the wildcard * instead of filename.exe but I do not suggest to do that as in that might mess up something with the .exe from the main cpp file and what not.

How to set the library suffix on CMake for SOCI?

I am trying to build SOCI on Windows with a different library suffix using the CMAKE_SHARED_LIBRARY_SUFFIX option, but the script seems to ignore it.
Here is the command I run in a batch file:
cmake^
-G "NMake Makefiles"^
-DCMAKE_BUILD_TYPE=Release^
-DCMAKE_SHARED_LIBRARY_SUFFIX="-vc140-x64-mt.dll"^
..\soci.3.2.3
The documentation does not say anything about the CMAKE_SHARED_LIBRARY_SUFFIX option, but the core/CMakeLists.txt script uses it to define the SOCI_LIB_SUFFIX option, which is reported on the screen when cmake is run. However, its value is always ".dll" instead of "-vc140-x64-mt.dll", so it must be overwritten somewhere I don't know.
Any idea why is this happening and how fix it?

Qt 5.x embedded debugging - deploy stripped binary?

I believe (correct me if I'm wrong) that when remote debugging with gdb and gdbserver, the binary running on the target under gdbserver doesn't need the debug information in the binary, but the host, running gdb, does.
Our application binary with debugging symbols is about 112 megs (!). If I run strip, the binary is only 6.7 megs, which would be much faster to deploy to our target.
Is it possible to have Qt Creator strip the binary before deploying it? Will we still be able to debug?
To strip symbols, you can have Qt Creator run a final build step after qmake and make, which calls the 'strip' command on the binary in your app bundle. For example: -
strip -u -r ./MyApplication/Contents/MacOS/MyApplication
In order to debug, you'd need a separate .dsym file to be generated during the build, which contains the symbols. If this resides on the host, the debugger should automatically pick this up; it does with lldb, though with gdb, you may need to manually load the symbol file.
how to enable that extra build step
Select projects from the right-side tool bar
Ensure you're on the Build and Run tab (GraphicsScene is just the name of the project)
Under Build Steps, you'll see two steps, qMake and Make. Select add build step for a custom process step
Fill in the relevant fields you may need to correct for the paths, rather than just copy these:
When the build has finished, the strip command will run. If you've any errors, it's likely a problem with the path to either the strip command or the path to your app bundle's executable.
Note that if you need the full path to strip, it resides in /usr/bin/strip.
As for the symbol file, I believe you can use the addsymbolfilecommand with the argument to the path to the dsym file. However, gdb has since been deprecated and you should really be using lldb now, which automatically finds the dsym file, once it has been indexed by Spotlight.
You can strip the debug symbols like this:
Add a line to your make file, this will remove all debug symbols from it:
cd $(MY_BINARY_INSTALL_PATH); strip --strip-debug $(MY_BINARY_INSTALL_PATH)/bin/mybinary -o $(MY_BINARY_INSTALL_PATH)/bin/mybinary
If you want to remove all symbols from it you could use something like:
cd $(MY_BINARY_INSTALL_PATH); strip --strip-all $(MY_BINARY_INSTALL_PATH)/bin/mybinary -o $(MY_BINARY_INSTALL_PATH)/bin/mybinary
Stripping all symbols will help reduce the size of the binary significantly

How to compile and execute a stand-alone SML-NJ executable

I have seen one other answer link but what I don't understand is what is basis.cm and what's it's use?
You are asking two questions.
What is basis.cm and what's it's use?
This is the Basis library. It allows the use of built-in functions.
How to compile and execute a stand-alone SML-NJ executable
Assuming you followed Jesper Reenberg's tutorial on how to execute a heap image, the next thing you need in order to have SML/NJ produce a stand-alone executable is to convert this heap image. One should hypothetically be able to do this using heap2exec, a tool that takes the heap image, e.g. the .x86-linux file generated on my system, and generates an .asm file that can be assembled and linked.
Unfortunately, this tool is not very well-maintained, so you have to
Go to the smlnj.org page and fix the download-link by removing 'www.' (this page and the SourceForge page don't contain the same explanations or assumptions about argument count, and neither page's download link work).
Download and extract this tool, and fix the 'build' script so it points to your ml-build tool
Fix the tool's argument use by changing [inf, outf] to [_, inf, outf]
Run ./build which generates 'heap2asm.x86-linux' on my system
For example, in order to generate an .asm file for the heap2asm program itself, run
sml #SMLload heap2asm.x86-linux heap2asm.x86-linux heap2asm.s
At this point, I have unfortunately been unable to produce an executable that works. E.g. if you run gcc -c heap2asm.s and ld heap2asm.o, you get a warning of a missing _start label. The resulting executable segfaults even if you rename the existing _sml_heap_image label to _start. That is, it seems that a piece of entry code that the runtime environment normally delivers is missing here.
At this point, discard SML/NJ and use MLton for producing stand-alone binaries.

Boost in Netbeans 7.1.1

Trying to run the following:
#include<iostream>
#include<boost/filesystem/operations.hpp>
namespace bfs=boost::filesystem;
int main()
{
bfs::path p("second.cpp");
if(bfs::exists(p))
std::cout<<p.leaf()<<std::endl;
}
I got some errors in cygwin so I decided to try out netbeans, and used the following as a guide. I added all links and the following for filesystem Project -> properties -> Linker ->Libraries -> Add option -> Other -> -lfile_system as noted here. I have run a separate test using #include<boost/any.hpp> so I am not currently doubting that my boost is not installed correclty.
It seems weird to me that it is "file_system", so I also tried "filesystem" but to no avail.
When i hold Ctrl and click on #include<boost/filesystem/operations.hpp> my netbeans brings up my operations.hpp file so it seems okay (linked properly internally that it can "see" what I want it to see).
The solution to installing boost came in the following form:
1 - If you have any path variables that are being used for Visual Studio you should temporarily change the variable during installation. This is a good guide. Once that is done, this is one step completed.
2 - Download and install MinGW. This is a very easy process and you can find the installer files here.
Once you have done these things (if you are in the same situation as me), you will now be able to properly install boost.
Horay!
Using Boost with cygwin step by step
Create a new Project
It is better to take the names given here in this tutorial exactly. Later ask: It does not work, can then be easier to find.
I do not think I need to mention all T:\ must of course be replaced with your drive.
Project Name : Boost-cyg-Test
Now your Project should look like
Open main.cpp
Overwrite the generated code with the following. We want to that, first of all everything works without error.
Therefore, please do not use your own special code.
It is difficult to find a fault. Then told after several ask, to get:
I have used my own code
#include <iostream>
#include <boost/filesystem.hpp>
using namespace std;
using namespace boost::filesystem;
int main()
{
path p("second.cpp");
if (exists(p)) { std::cout<<p.leaf()<<std::endl; }
}
In this section we assume that "boost" is already compiled.
goto Tools -> Options
Your C++ Code Assistance options should look something like this.
If this is not so, we should let Netbeans create that for us.
Add New Tool Collection
After we have completed this dialog with OK, we should find the settings shown above. ( C++ Code Assistance options).
Copy all libs into the right place
Let's create a new folder 'boost'.
With a search tool, search in your compiled Boost folder for *.a
My Boost is compiled with the shared option so we find :
For our short App. we need only 2 files.
libboost_filesystem-gcc45-mt-d-1_53.dll.a
libboost_system-gcc45-mt-d-1_53.dll.a
But if we're at it to copy two files, we can copy all files.
So mark all found .a files and copy them into the directory just created
T:\cygwin\lib\boost .
Now we do the same with our .dll files.
Mark all .dll files and copy it in your ?:\cygwin\bin directory.
If you only have compiled static librarys, you can skip this point.
Now it's time to modify our project settings.
As you can see i put my source Boost folder into cygwin
and
As we have already noted above, we need two .a files.
with Add Library navigate to T:\cygwin\lib\boost and select
libboost_filesystem-gcc45-mt-d-1_53.dll.a
libboost_system-gcc45-mt-d-1_53.dll.a
Now you'll notice that this name was shortened by netbeans to:
boost_filesystem-gcc45-mt-d-1_53.dll
boost_system-gcc45-mt-d-1_53.dll
This is somewhat confusing. It looks as if a .dll is standing here. But it is really a .a file.
Set a breakpoint in main.cpp. Now we start debug.
I have marked the important part, the two libs, with an arrow.
All libs are found and after make has finished, stops at the breakpoint.
The output:
Build Boost for Cygwin
For all who want to create boost with shared library itself.
Download boost_1_53_0.zip
Create a folder in your ?:\cygwin directory.
boost_1_53_0
Extract the zip file into that directory.
It should look like:
open a cmd window, cd to boost_1_53_0 directory.
To have a clean build we need a PATH that have only the cygwin home and bin.
In the cmd type.
SET PATH=T:\cygwin;T:\cygwin\bin
and test the path.
PATH
Type
bootstrap.bat
Type
.\b2 --build-dir=T:\boost-cyg toolset=gcc variant=debug link=shared runtime-link=shared
After some time the build is finished.
Now you have the same environment that we have used in the tutorial.
If you get a Error : gcc not found
copy (not rename) in ?:\cygwin\bin folder, for example : (names may differ).
i686-pc-cygwin-gcc-4.5.3.exe to gcc.exe
and
i686-pc-cygwin-g++-4.exe to g++.exe
Hope it helps you.
Could you paste the error you get when compiling ?
I am not used to compile programs in a Windows environment, but I think as Jesse Good suggested in a comment that you have a linker error.
You may solve it by using -lboost_filesystem instead of lfile_system.
To find out how your libs are called, you get the name of your lib (on my unix environment I have libboost_filesystem.so), strip the "lib" prefix and the ".so" or ".a" suffix (must be different in a Windows environment).
if your boost installation is correct and you are sure about it then for Unable to resolve identifier try Code Assistance->Reparse Project from context menu of the project. It tries to recover broken code model by reparsing project from scratch. if that didn't workout try closing IDE and removing code model cache.
p.s. do you have compilation errors?