66

Is there any way a program can crash before main()?

8
  • I know I've seen this before, but it was so long ago I'm not sure if I can remember the cause. Commented Mar 25, 2010 at 18:52
  • 31
    I can confidently say that I can cause anything to crash at any time. :) Commented Mar 25, 2010 at 19:25
  • 2
    @Mark Allen: forgive the misspelling of your name; still mopping up tea! Commented Mar 25, 2010 at 19:53
  • 6
    If you are running windows, it can crash at any time, without any explainable reason. Commented Mar 27, 2010 at 16:56
  • 6
    Yes, of course, because it's only ever Windows that crashes inexplicably. The term "kernel panic" doesn't exist in the Linux world at all.</sarcasm> Commented Apr 4, 2010 at 1:00

18 Answers 18

37

With gcc, you can tag a function with the constructor attribute (which causes the function to be run before main). In the following function, premain will be called before main:

#include <stdio.h> void premain() __attribute__ ((constructor)); void premain() { fputs("premain\n", stdout); } int main() { fputs("main\n", stdout); return 0; } 

So, if there is a crashing bug in premain you will crash before main.

Sign up to request clarification or add additional context in comments.

4 Comments

Why would you want to do this? Why not just call that in main?
@Victor: For example it could be added in a lib archive so you won't see, initializing some library part.
Maybe if your code is in a shared library, and you don't want to have to require all users of the shared library to put a call to premain() inside of their main() (because they'll all forget to do it anyway :))
+1 @R Samuel Klatchko: That for this answer, I have a use for it already.
34

Yes, at least under Windows. If the program utilizes DLLs they can be loaded before main() starts. The DllMain functions of those DLLs will be executed before main(). If they encounter an error they could cause the entire process to halt or crash.

1 Comment

how to debug such problems?
20

If you have a C++ program it can initialize variables and objects through functions and constructors before main is entered. A bug in any of these could cause a program to crash.

3 Comments

The question is about C, not C++.
@GMan, ...any perfect system used by man will ultimately fail?
20

The simple answer is: Yes.

More specifically, we can differentiate between two causes for this. I'll call them implementation-dependent and implementation-independent.

The one case that doesn't depend on your environment at all is that of static objects in C++, which was mentioned here. The following code dies before main():

#include <iostream> class Useless { public: Useless() { throw "You can't construct me!"; } }; static Useless object; int main() { std::cout << "This will never be printed" << std::endl; return 0; } 

More interesting are the platform-dependent causes. Some were mentioned here. One that was mentioned here a couple of times was the usage of dynamically linked libraries (DLLs in windows, SOs in Linux, etc.) - if your OS's loader loads them before main(), they might cause your application do die before main().

A more general version of this cause is talking about all the things your binary's entry point does before calling your entry point(main()). Usually when you build your binary there's a pretty serious block of code that's called when your operating system's loader starts to run your binary, and when it's done it calls your main(). One common thing this code does is initializing the C/C++ standard library. This code can fail for any number of reasons (shortage of any kind of system resource it tries to allocate for one).

One interesting way on for a binary to execute code before main() on windows is using TLS callbacks (google will tell you more about them). This technique is usually found in malware as a basic anti-debugging trick (this trick used to fool ollydbg back then, don't know if it still does).

The point is that your question is actually equivalent to "is there a way that loading a binary would cause user code to execute before the code in main()?", and the answer is hell, yeah!

Comments

18

certainly in c++; static objects with contructors will get called before main - they can die

not sure about c

here is sample

class X { public: X() { char *x = 0; *x = 1; } }; X x; int main() { return 0; } 

this will crash before main

2 Comments

The question is about C, not C++.
@Thi Then say so, by using tags and the question title and text! But this is a good question about C, and a not so good one about C++, because the answer in that case is trivial - "yes".
11

Any program that relies on shared objects (DLLs) being loaded before main can fail before main.

Under Linux code in the dynamic linker library (ld-*.so) is run to supply any library dependancies well before main. If any needed libraries are not able to be located, have permissions which don't allow you to access them, aren't normal files, or don't have some symbol that the dynamic linker that linked your program thought that it should have when it linked your program then this can cause failure.

In addition, each library gets to run some code when it is linked. This is mostly because the library may need to link more libraries or may need to run some constructors (even in a C program, the libraries could have some C++ or something else that uses constroctors). In addition, standard C programs have already created the stdio FILEs stdin, stdout, and stderr. On many systems these can also be closed. This implies that they are also free()ed, which implies that they (and their buffers) were malloc()ed, which can fail. It also suggests that they may have done some other stuff to the file descriptors that those FILE structures represent, which could fail.

Other things that could possibly happen could be if the OS were to mess up setting up the enviromental variables and/or command line arguments that were passed to the program. Code before main is likely to have had to something with this data before calling main.

Lots of things happen before main. Any of them can concievably fail in a fatal way.

Comments

6

I'm not sure, but if you have a global variable like this :

static SomeClass object; int main(){ return 0; } 

The 'SomeClass' constructor could possibly crash the program before the main being executed.

4 Comments

Pretty hard to have a class constructor in C, which the question is tagged with.
The question is about C, not C++.
I was assuming the case of C++, anyway if it's only C related i really don't know. Anyway, it's ok, next time i'll pay more attention to tags.
@smerlin, only added after the fact.
5

There are many possibilities.

First, we need to understand what actually goes on before main is executed:

  • Load of dynamic libraries
  • Initialization of globals
  • One some compilers, some functions can be executed explicitly

Now, any of this can cause a crash in several ways:

  • the usual undefined behavior (dereferencing null pointer, accessing memory you should not...)
  • an exception thrown > since there is no catch, terminate is called and the program end

It's really annoying of course and possibly hard to debug, and that is why you should refrain from executing code before main as much as possible, and prefer lazy initialization if you can, or explicit initialization within main.

Of course, when it's a DLL failing and you can't modify it, you're in for a world of pain.

Comments

4

Sort of: http://blog.ksplice.com/2010/03/libc-free-world/

If you compile without standard library, like this: gcc -nostdlib -o hello hello.c

it won't know how to run main() and will crash.

Comments

3

Global and static objects in a C++ program will have their constructors called before the first statement in main() is executed, so a bug in one of the constructors can cause a crash.

This can't happen in C programs, though.

Comments

3

It depends what you mean by "before main", but if you mean "before any of your code in main is actually executed" then I can think of one example: if you declare a large array as a local variable in main, and the size of this array exceeds the available stack space, then you may well get a stack overflow on entry to main, before the first line of code executes.

2 Comments

I see now you had the array idea first. But why do you want to make it local? Just give it file-scope. A char big[-1U / 2U]; at file-scope causes a crash too here.
@johannes: yes, that probably works too - the local array in main only needs to be 8 MB or so though, depending on the default stack size for your OS, so it's a little more subtle than your sledgehammer approach with a humungous array. ;-)
2

A somewhat contrived example would be:

int a = 1; int b = 0; int c = a / b; int main() { return 0; } 

It's unlikely that you'd ever do something like this, but if you're doing a lot of macro-magic, it is entirely possible.

2 Comments

gcc 4.4 won't compile this: t.c:3: error: initializer element is not constant
it compiled fine in vs 2005. gcc is stricter with this kind of stuff and that's definitely a good thing. :) I was just making a point that this kind of behavior can be produced with clever macro computations and such, stuff that is all too common in C.
2
class Crash { public: Crash( int* p ) { *p = 0; } }; static Crash static_crash( 0 ); void main() { } 

Comments

2

I had faced the same issue. The root-cause found was.. Too many local variables(huge arrays) were initialized in the main process leading the local variables size exceeding 1.5 mb.
This results in a big jump as the stack pointer is quite large and the OS detects this jump as invalid and crashes the program as it could be malicious.

To debug this.
1. Fire up GDB
2. Add a breakpoint at main
3. disassemble main
4. Check for sub $0xGGGGGGG,%esp
If this GGGGGG value is too high then you will see the same issue as me.

So check the total size of all the local variables in the main.

3 Comments

The Solution to this is to remove the huge array initialization and malloc them instead.
Is there any way to increase the memory used so that large arrays can be initialized/
I am not sure if we can do this.. This might require a kernel change I assume
1

Sure, if there's a bug in the operating system or the runtime code. C++ is particularly notorious for this behaviour, but it can still happen in C.

3 Comments

downvote is unfair... one up to be fair and because it is a valid hypothesis.
Although I haven't voted down, I guess it's the polemic side blow to C++'s alleged bad reputation.
I guess so - but C++ programs do have this problem all the time.
1

You haven't said which platform/libc. In the embedded world there are frequently many things which run before main() - largely to do with platform setup - which can go wrong. (Or indeed if you are using a funky linker script on a regular OS, all bets are off, but I guess that's pretty rare.)

Comments

1

some platform abstraction libraries override (i personally only know of C++ libraries like Qt or ACE, which do this, but maybe some C libraries do something like that aswell) "main", so that they specify a platform-specific main like a int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ); and setup some library stuff, convert the command line args to the normal int argc, char* argv[] and then call the normal int main(int argc, char* argv[])

Of course such libraries could lead to a crash when they did not implement this correctly (maybe cause of malformed command line args).

And for people who dont know about this, this may look like a crash before main

Comments

0

Best suited example to crash a program before main for stackoverflow:

int main() { char volatile stackoverflow[1000000000] = {0}; return 0; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.