Sorry for such a noobie question, I have just never encountered this before, I look online but can only find descriptions of what argc, and argv are.
Anyway, I started a new win32 console project in visual studio 2012. I clicked empty project, and began by adding program.cpp with which the contents are the following:
#include <iostream>
#include <Windows.h>
int main(int argc, char** argv)
{
printf( "%d", argc );
getchar();
return 0;
}
I am planning to use arguments to make a program, which is why I need argc to be working properly. The code about outputs a huge number like '21374903'. In properties -> linker -> advanced I set the entry point to 'main'.
Is there anything I'm doing wrong? Can I add a setting to make it work properly?
In properties -> linker -> advanced I set the entry point to 'main'.
Don't do that. The entry point needs to be the C Runtime (CRT) entry point, which performs C initialization, obtains the arguments from the operating system, and calls your main function with them.
If you don't explicitly tell the linker what the entry point is named, it will automatically pick the right one. The CRT entry point that calls main is named mainCRTStartup (there are other CRT entry points with other names that call the other kinds of main functions supported by Visual C++).
Related
I have simple C++ programm:
#include <iostream>
using namespace std;
void main()
{
cout << "Hello, world, from Visual C++!" << endl;
}
Compiled with following command: cl /EHsc hello.cpp
I want to start debugging of executable, How can I find this main function's corresponding assembly code in the debugger? (I'm using x64dbg)
Entry point is not same as Main function.
I found main function and it is somewhere not near with Entry Point, I had strings and I found this easily.
Is there any way or rule or best practise how to guess where is main's corresponding assmebly code?
EDIT:
I have source code, but I just learning RE.
Although the entry point is usually not the main defined in your executable, this is merely because it is quite common for compilers to to wrap main with some initialization code.
In most cases the initialization code is quite similar and has one of few versions per compiler. Most of those functions have an IDA FLIRT signature, and opening the binary with IDA will define an WinMain, main, etc function for you automatically. You can also use free (trial) versions of IDA for that.
If that's not the case, it's pretty straight forward to get from the entrypoint to the main, by following the few calls inside the entrypoint function one level deep. the main call is usually near the end of the entrypoint function.
Here's an example, main function is selected near the bottom (Note this is a unix executable compiled for windows using mingw, so this is somewhat different from most native win32 executables).
if you debugging own code - the best way to stop somewhere under debugger - use next code
if (IsDebuggerPresent()) __debugbreak();
so you can insert it at begin of your main or any other places.
if you debugging not own binary code - binary can at all not containing c/c++ CRT code - so question became senseless. however if CRT code exist, despite many different implementations - all use common patterns and after some practice - possible found where CRT code call main.
in case standard windows binaries, for which exist pdb files - this is not a problem at all
Generally, you can't.
When you compile a program, you get a binary and (optionally) debugging symbols.
If you have the debugging symbols, let IDA or your debugger load them, and then you should be able to symbolically evaluate main to the address of the function (e.g in IDA, just press g and write main and you'll be there. In WinDbg or gdb you can type b main)
However, the more common case would be to find the main function on a binary for which you do not posses the debugging symbols. In this case, you don't know where the main function is, nor if it is even there. The binary may not use the common libc practice of an entry point doing initialization and then calling main(int argc, char *argv[], char *envp[]).
But because you're an intelligent human, I'd recommended reading the libc implementation for the compiler/platform you think you're working with, and follow the logic from the platform-defined entry point until you see the call main instruction.
(Please note that .NET binaries and other types of binaries may behave completely differently.)
After having some trouble setting up SDL, I found out that SDL defines a macro that replaces main:
#define main SDL_main
// And then
extern C_LINKAGE int SDL_main(int argc, char *argv[]);
This can also create compilation errors, if the main function doesn't have the argc and argv parameters defined.
This macro gives me headaches just when I see it... Why does SDL need to redefine main? After some more searching, I found that some people #undef main, and use it the normal way.
So this is the question: why does SDL need to redefine main, what does it do? Are there any side effects to undefining it?
One thing I noticed is that SDL redirects standard output and error to files (and I don't want this behavior), and this behavior stops if I undefine main.
Per the SDL Windows FAQ:
You should be using main() instead of WinMain() even though you are creating a Windows application, because SDL provides a version of WinMain() which performs some SDL initialization before calling your main code.
If for some reason you need to use WinMain(), take a look at the SDL source code in src/main/win32/SDL_main.c to see what kind of initialization you need to do in your WinMain() function so that SDL works properly.
SDL requires initialization, so it injects its own main function that runs its initialization before calling your "main" function, which it renames to SDL_main so that it does not conflict with the actual main function. As noted in the FAQ, your main function must be of the form
int main(int argc, char* argv[])
While I agree that it's a strange practice, there are situations where this is a reasonable solution, though it largely depends on the platform. Consider that different platforms have different entry points. Windows is typically WinMain, Linux is main, interacting with Android happens in Java, WinRT uses C++/CX extensions, and so on. Program entry point and APIs can be very platform specific and SDL tries to save you the trouble of having to deal with this. If you're only targeting Windows and SDL is only there to save you the trouble of working with WIN32 API, you might not need it. But if you ever go beyond desktop, you'll find it useful in my opinion.
I am so frustrated with the Microsoft C++ compiler (not Visual). I am really annoyed at how it uses
int _tmain(
and
_TCHAR* argv[]
as well as many other things. I just want to use straight C++ like you would in GCC. Is there an alternative?
Thanks to all the responses. I was really just looking for a way of not using Microsoft Style code. This is what helped me -
Remove #include "stdafx.h"
Rename main method to -
int main (int argc, char* argv[])
{
return 0;
}
And it works!
You don't have to use _tmain() and TCHAR if you do not want to. Just create an empty project, add an empty source file to it and start writing
int main(int argc, char* argv[])
{
}
On VC++ 2010 Express you can just compile and execute it straight away. I don't remember if previous versions require that you set the project type.
You can try MinGW-32/64 for windows.
The _tmain/_TCHAR stuff is optional (you can read more about this on MSDN, Generic-Text Mappings in Tchar.h). You can delete the tchar.h file and #include from your project and directly use wmain/wchar_t (or main/char for ANSI) if you so choose.
You can get gcc for Windows. Look at the cygwin site. I know MS lets you use _tmain, TCHAR etc, but its the first I've heard that it actually requires you do to so, are you sure you're not missing some option somehere?
You can try gcw and MinGW but I have had varying results with both so YMMV...
From what I can tell you can kick off all the action in a constructor when you create a global object. So do you really need a main() function in C++ or is it just legacy?
I can understand that it could be considered bad practice to do so. I'm just asking out of curiosity.
If you want to run your program on a hosted C++ implementation, you need a main function. That's just how things are defined. You can leave it empty if you want of course. On the technical side of things, the linker wants to resolve the main symbol that's used in the runtime library (which has no clue of your special intentions to omit it - it just still emits a call to it). If the Standard specified that main is optional, then of course implementations could come up with solutions, but that would need to happen in a parallel universe.
If you go with the "Execution starts in the constructor of my global object", beware that you set yourself up to many problems related to the order of constructions of namespace scope objects defined in different translation units (So what is the entry point? The answer is: You will have multiple entry points, and what entry point is executed first is unspecified!). In C++03 you aren't even guaranteed that cout is properly constructed (in C++0x you have a guarantee that it is, before any code tries to use it, as long as there is a preceeding include of <iostream>).
You don't have those problems and don't need to work around them (wich can be very tricky) if you properly start executing things in ::main.
As mentioned in the comments, there are however several systems that hide main from the user by having him tell the name of a class which is instantiated within main. This works similar to the following example
class MyApp {
public:
MyApp(std::vector<std::string> const& argv);
int run() {
/* code comes here */
return 0;
};
};
IMPLEMENT_APP(MyApp);
To the user of this system, it's completely hidden that there is a main function, but that macro would actually define such a main function as follows
#define IMPLEMENT_APP(AppClass) \
int main(int argc, char **argv) { \
AppClass m(std::vector<std::string>(argv, argv + argc)); \
return m.run(); \
}
This doesn't have the problem of unspecified order of construction mentioned above. The benefit of them is that they work with different forms of higher level entry points. For example, Windows GUI programs start up in a WinMain function - IMPLEMENT_APP could then define such a function instead on that platform.
Yes! You can do away with main.
Disclaimer: You asked if it were possible, not if it should be done. This is a totally un-supported, bad idea. I've done this myself, for reasons that I won't get into, but I am not recommending it. My purpose wasn't getting rid of main, but it can do that as well.
The basic steps are as follows:
Find crt0.c in your compiler's CRT source directory.
Add crt0.c to your project (a copy, not the original).
Find and remove the call to main from crt0.c.
Getting it to compile and link can be difficult; How difficult depends on which compiler and which compiler version.
Added
I just did it with Visual Studio 2008, so here are the exact steps you have to take to get it to work with that compiler.
Create a new C++ Win32 Console Application (click next and check Empty Project).
Add new item.. C++ File, but name it crt0.c (not .cpp).
Copy contents of C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\crt0.c and paste into crt0.c.
Find mainret = _tmain(__argc, _targv, _tenviron); and comment it out.
Right-click on crt0.c and select Properties.
Set C/C++ -> General -> Additional Include Directories = "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src".
Set C/C++ -> Preprocessor -> Preprocessor Definitions = _CRTBLD.
Click OK.
Right-click on the project name and select Properties.
Set C/C++ -> Code Generation -> Runtime Library = Multi-threaded Debug (/MTd) (*).
Click OK.
Add new item.. C++ File, name it whatever (app.cpp for this example).
Paste the code below into app.cpp and run it.
(*) You can't use the runtime DLL, you have to statically link to the runtime library.
#include <iostream>
class App
{
public: App()
{
std::cout << "Hello, World! I have no main!" << std::endl;
}
};
static App theApp;
Added
I removed the superflous exit call and the blurb about lifetime as I think we're all capable of understanding the consequences of removing main.
Ultra Necro
I just came across this answer and read both it and John Dibling's objections below. It was apparent that I didn't explain what the above procedure does and why that does indeed remove main from the program entirely.
John asserts that "there is always a main" in the CRT. Those words are not strictly correct, but the spirit of the statement is. Main is not a function provided by the CRT, you must add it yourself. The call to that function is in the CRT provided entry point function.
The entry point of every C/C++ program is a function in a module named 'crt0'. I'm not sure if this is a convention or part of the language specification, but every C/C++ compiler I've come across (which is a lot) uses it. This function basically does three things:
Initialize the CRT
Call main
Tear down
In the example above, the call is _tmain but that is some macro magic to allow for the various forms that 'main' can have, some of which are VS specific in this case.
What the above procedure does is it removes the module 'crt0' from the CRT and replaces it with a new one. This is why you can't use the Runtime DLL, there is already a function in that DLL with the same entry point name as the one we are adding (2). When you statically link, the CRT is a collection of .lib files, and the linker allows you to override .lib modules entirely. In this case a module with only one function.
Our new program contains the stock CRT, minus its CRT0 module, but with a CRT0 module of our own creation. In there we remove the call to main. So there is no main anywhere!
(2) You might think you could use the runtime DLL by renaming the entry point function in your crt0.c file, and changing the entry point in the linker settings. However, the compiler is unaware of the entry point change and the DLL contains an external reference to a 'main' function which you're not providing, so it would not compile.
Generally speaking, an application needs an entry point, and main is that entry point. The fact that initialization of globals might happen before main is pretty much irrelevant. If you're writing a console or GUI app you have to have a main for it to link, and it's only good practice to have that routine be responsible for the main execution of the app rather than use other features for bizarre unintended purposes.
Well, from the perspective of the C++ standard, yes, it's still required. But I suspect your question is of a different nature than that.
I think doing it the way you're thinking about would cause too many problems though.
For example, in many environments the return value from main is given as the status result from running the program as a whole. And that would be really hard to replicate from a constructor. Some bit of code could still call exit of course, but that seems like using a goto and would skip destruction of anything on the stack. You could try to fix things up by having a special exception you threw instead in order to generate an exit code other than 0.
But then you still run into the problem of the order of execution of global constructors not being defined. That means that in any particular constructor for a global object you won't be able to make any assumptions about whether or not any other global object yet exists.
You could try to solve the constructor order problem by just saying each constructor gets its own thread, and if you want to access any other global objects you have to wait on a condition variable until they say they're constructed. That's just asking for deadlocks though, and those deadlocks would be really hard to debug. You'd also have the issue of which thread exiting with the special 'return value from the program' exception would constitute the real return value of the program as a whole.
I think those two issues are killers if you want to get rid of main.
And I can't think of a language that doesn't have some basic equivalent to main. In Java, for example, there is an externally supplied class name who's main static function is called. In Python, there's the __main__ module. In perl there's the script you specify on the command line.
If you have more than one global object being constructed, there is no guarantee as to which constructor will run first.
If you are building static or dynamic library code then you don't need to define main yourself, but you will still wind up running in some program that has it.
If you are coding for windows, do not do this.
Running your app entirely from within the constructor of a global object may work just fine for quite awhile, but sooner or later you will make a call to the wrong function and end up with a program that terminates without warning.
Global object constructors run during the startup of the C runtime.
The C runtime startup code runs during the DLLMain of the C runtime DLL
During DLLMain, you are holding the DLL loader lock.
Tring to load another DLL while already holding the DLL loader lock results in a swift death for your process.
Compiling your entire app into a single executable won't save you - many Win32 calls have the potential to quietly load system DLLs.
There are implementations where global objects are not possible, or where non-trivial constructors are not possible for such objects (especially in the mobile and embedded realms).
I was asked an interview question to change the entry point of a C or C++ program from main() to any other function. How is it possible?
In standard C (and, I believe, C++ as well), you can't, at least not for a hosted environment (but see below). The standard specifies that the starting point for the C code is main. The standard (c99) doesn't leave much scope for argument:
5.1.2.2.1 Program startup: (1) The function called at program startup is named main.
That's it. It then waffles on a bit about parameters and return values but there's really no leeway there for changing the name.
That's for a hosted environment. The standard also allows for a freestanding environment (i.e., no OS, for things like embedded systems). For a freestanding environment:
In a freestanding environment (in which C program execution may take place without any benefit of an operating system), the name and type of the function called at program startup are implementation-defined. Any library facilities available to a freestanding program, other than the minimal set required by clause 4, are implementation-defined.
You can use "trickery" in C implementations so that you can make it look like main isn't the entry point. This is in fact what early Windows compliers did to mark WinMain as the start point.
First way: a linker may include some pre-main startup code in a file like start.o and it is this piece of code which runs to set up the C environment then call main. There's nothing to stop you replacing that with something that calls bob instead.
Second way: some linkers provide that very option with a command-line switch so that you can change it without recompiling the startup code.
Third way: you can link with this piece of code:
int main (int c, char *v[]) { return bob (c, v); }
and then your entry point for your code is seemingly bob rather than main.
However, all this, while of possibly academic interest, doesn't change the fact that I can't think of one single solitary situation in my many decades of cutting code, where this would be either necessary or desirable.
I would be asking the interviewer: why would you want to do this?
The entry point is actually the _start function (implemented in crt1.o) .
The _start function prepares the command line arguments and then calls main(int argc,char* argv[], char* env[]),
you can change the entry point from _start to mystart by setting a linker parameter:
g++ file.o -Wl,-emystart -o runme
Of course, this is a replacement for the entry point _start so you won't get the command line arguments:
void mystart(){
}
Note that global/static variables that have constructors or destructors must be initialized at the beginning of the application and destroyed at the end. Keep that in mind if you are planning on bypassing the default entry point which does it automatically.
From C++ standard docs 3.6.1 Main Function,
A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined
whether a program in a freestanding environment is required to define a main function.
So, it does depend on your compiler/linker...
If you are on VS2010, this could give you some idea
As it is easy to understand, this is not mandated by the C++ standard and falls in the domain of 'implemenation specific behavior'.
This is highly speculative, but you might have a static initializer instead of main:
#include <iostream>
int mymain()
{
std::cout << "mymain";
exit(0);
}
static int sRetVal = mymain();
int main()
{
std::cout << "never get here";
}
You might even make it 'Java-like', by putting the stuff in a constructor:
#include <iostream>
class MyApplication
{
public:
MyApplication()
{
std::cout << "mymain";
exit(0);
}
};
static MyApplication sMyApplication;
int main()
{
std::cout << "never get here";
}
Now. The interviewer might have thought about these, but I'd personally never use them. The reasons are:
It's non-conventional. People won't understand it, it's nontrivial to find the entry point.
Static initialization order is nondeterministic. Put in another static variable and you'll never now if it gets initialized.
That said, I've seen it being used in production instead of init() for library initializers. The caveat is, on windows, (from experience) your statics in a DLL might or might not get initialized based on usage.
Modify the crt object that actually calls the main() function, or provide your own (don't forget to disable linking of the normal one).
With gcc, declare the function with attribute((constructor)) and gcc will execute this function before any other code including main.
For Solaris Based Systems I have found this. You can use the .init section for every platforms I guess:
pragma init (function [, function]...)
Source:
This pragma causes each listed function to be called during initialization (before main) or during shared module loading, by adding a call to the .init section.
It's very simple:
As you should know when you use constants in c, the compiler execute a kind of 'macro' changing the name of the constant for the respective value.
just include a #define argument in the beginning of your code with the name of start-up function followed by the name main:
Example:
#define my_start-up_function (main)
I think it is easy to remove the undesired main() symbol from the object before linking.
Unfortunately the entry point option for g++ is not working for me(the binary crashes before entering the entry point). So I strip undesired entry-point from object file.
Suppose we have two sources that contain entry point function.
target.c contains the main() we do not want.
our_code.c contains the testmain() we want to be the entry point.
After compiling(g++ -c option) we can get the following object files.
target.o, that contains the main() we do not want.
our_code.o that contains the testmain() we want to be the entry point.
So we can use the objcopy to strip undesired main() function.
objcopy --strip-symbol=main target.o
We can redefine testmain() to main() using objcopy too.
objcopy --redefine-sym testmain=main our_code.o
And then we can link both of them into binary.
g++ target.o our_code.o -o our_binary.bin
This works for me. Now when we run our_binary.bin the entry point is our_code.o:main() symbol which refers to our_code.c::testmain() function.
On windows there is another (rather unorthodox) way to change the entry point of a program: TLS. See this for more explanations: http://isc.sans.edu/diary.html?storyid=6655
Yes,
We can change the main function name to any other name for eg. Start, bob, rem etc.
How does the compiler knows that it has to search for the main() in the entire code ?
Nothing is automatic in programming.
somebody has done some work to make it looks automatic for us.
so it has been defined in the start up file that the compiler should search for main().
we can change the name main to anything else eg. Bob and then the compiler will be searching for Bob() only.
Changing a value in Linker Settings will override the entry point. i.e., MFC applications use a value of 'Windows (/SUBSYSTEM:WINDOWS)' to change entry point from main() to CWinApp::WinMain().
Right clicking on solution > Properties > Linker > System > Subsystem > Windows (/SUBSYSTEM:WINDOWS)
...
Very practical benefit to modifying entry point:
MFC is a framework we take advantage of to write Windows applications in C++. I know it's ancient, but my company maintains one for legacy reasons! You will not find a main() in MFC code. MSDN says the entry point is WinMain(), instead. Thus, you can override the WinMain() of your base CWinApp object. Or, most people override CWinApp::InitInstance() because the base WinMain() will call it.
Disclaimer: I use empty parentheses to denote a method, without caring how many arguments.