Assertion macro

Posted By: WretchedSid

Assertion macro - 10/04/10 14:38

Heyho, I made this small assertion macro for one of my projects:
Code:
#define LFAssert(condition, message) if(!(condition)){error(message); sys_exit(NULL);}



Here is how I use it:
Code:
LFAssert(foopointer, "Some error message");



It compiles and runs great with the GCC (4.2) and LLVM (1.5, 1.6, 2.0) (same macro but printf() and abort() instead of error() und sys_exit()) but the Lite-C compiler refuses to accept the way I use it (A8.02)

Is there something that I miss or is this a bug?
Posted By: EvilSOB

Re: Assertion macro - 10/04/10 17:36

Youve missed the final ";" in your thinking...

Type-out the macro-replacement manually... and keep an eye on the red ";"
LFAssert(foopointer, "Some error message");
becomes
if(!(foopointer)){"Some error message"); sys_exit(NULL);};
You see?

I tend to "fake" this with a REALLY ugly hack like so...
Code:
#define LFAssert(con, msg) if(!(con)){error(msg); sys_exit(NULL);} var who_cares=0
//[[condition and message shortened just for display purposes...]]


which then becomes
if(!(foopointer)){"Some error message"); sys_exit(NULL);} var who_cares=0;

VERY ugly, but work MOST of the time...

Mind you, I wish there was a better way...
Posted By: WretchedSid

Re: Assertion macro - 10/04/10 17:58

I can't believe it... what an annoying thing -.-
Really, a ; too much shouldn't be a problem and every C compiler I know of doesn't complain about it.

Thank you very much EvilSOB!
Posted By: JibbSmart

Re: Assertion macro - 10/04/10 18:26

Groovy, I was just yesterday thinking about using an assert macro to make my code a bit safer, and then saw this thread today.

I would personally use a function as well to avoid the hacky stuff (and potential double-definitions of who_cares [even though who_cars could be declared globally and then re-assigned in the assertion, I guess]):
Code:
function failAssert(char *msg) {
	error(msg);
	sys_exit(NULL);
}
#define assert(con, msg) if(!(con))failAssert(msg)


Jibb
Posted By: WretchedSid

Re: Assertion macro - 10/04/10 18:36

Okay, I found another thing, my fallback (#ifdef NDEBUG) looks like this:
Code:
#define LFAssert(condition, message) ((void) 0)



guess what, it isnt working... WHAT? Why? "Can't convert long to void"
My other fallback would be "asm ("nop");" but this also fails (feature request: Inline assembler!)
What do? D:

Edit: @JulzyMighty: I used a foo variable named "iLoveEvilSOB". I guess that no one uses a variable like this tongue
Btw, I just found a solution for my new problem... Just declare the variable again -.-
Posted By: JibbSmart

Re: Assertion macro - 10/04/10 19:16

Quote:
Edit: @JulzyMighty: I used a foo variable named "iLoveEvilSOB". I guess that no one uses a variable like this tongue
You could be surprised how many people use a variable named "iLoveEvilSOB" laugh
Quote:
My other fallback would be "asm ("nop");" but this also fails (feature request: Inline assembler!)
++. I wonder what jcl would say.

Jibb
Posted By: EvilSOB

Re: Assertion macro - 10/04/10 20:02

No one loves EvilSOB, but he's happy that way...
There is just a lot of SARCARSTIC peoples on this forum,
who are jealous of my extreme intelligence and humility grin
Posted By: EvilSOB

Re: Assertion macro - 10/04/10 20:04

Back to serious mode now. How about this...
Code:
function failAssert(char *msg) 
{
#ifdef NDEBUG
   return;
#endif
   error(msg);
   sys_exit(NULL);
}
#define assert(con, msg) if(!(con))failAssert(msg)


Is that the idea of the assert?
Posted By: WretchedSid

Re: Assertion macro - 10/04/10 20:21

I don't want this kind of assert because it isn't inlined like a #define is. Or at least it isn't inlined in the Lite-C compiler (feature request #2: inline functions).

But basically, yes, this would be the assert. Btw, I switched from the iLoveEvilSOB variable to an internal dummy variable with my own prefix.
Posted By: FBL

Re: Assertion macro - 10/04/10 20:27

struct iLoveJustSid?
Posted By: WretchedSid

Re: Assertion macro - 10/04/10 20:29

LFDummy
Posted By: FBL

Re: Assertion macro - 10/04/10 20:34

Minimum I'd have expected would be LFTestdummy laugh
Posted By: WretchedSid

Re: Assertion macro - 10/04/10 20:51

But it isn't a test dummy, it's just a random dummy =/
Posted By: FBL

Re: Assertion macro - 10/04/10 21:21

I was referring to the user =(
Posted By: jcl

Re: Assertion macro - 10/05/10 09:14

Back to topic: I'm using similar macros in my code, but I don't write the final ;. This reminds me that it's a macro and not a function.

A single ';' throws an error in lite-C because in most cases it is not intended, but caused by an error in the preceding line.
Posted By: WretchedSid

Re: Assertion macro - 10/05/10 10:04

Well, this wouldn't be a problem if SED would show macros in an extra color (automatically!). But at the moment it isn't visible for the user if it is an macro or a function. (Oh and just a side note, every code I have seen so far that uses assertion has an ; at the end, wether it is used or not).
However, the workaround works great and I don't see a problem in using this so this thread is more or less obsolete. BUT! What about the feature request inline assembler?
I don't need a full GCC style inline assembler, and would be enough if the compiler would just insert my assembler code to what it translates. Would this be possible?

Edit: FFFFFFFFUUUUUU, now this topic is moved and I guess JCL doesn't look into it anymore -.-
Posted By: jcl

Re: Assertion macro - 10/05/10 10:33

I still look into it, but no, there won't be an inline assembler.
Posted By: WretchedSid

Re: Assertion macro - 10/05/10 10:59

But why?
Posted By: Bunsen

Re: Assertion macro - 10/05/10 20:43

I don't assume, Conitec will offer an inline assembler feature within Lite-C.
The reason maybe is, that you could use a regular C/C++ Compiler to do this
and Lite-C should be as easy as possible. But if you need this in your
Lite-C project you may try this method.

For instance:

Code:
double fmod_native(double x, double y)
{
	double ptr(double,double);
	static char machine_code[] = {
		0x55,			// push ebp
		0x8B, 0xEC,		// mov ebp, esp
		0xDD, 0x45, 0x10,	// fld qword ptr [ebp+0x10]
		0xDD, 0x45, 0x08,	// fld qword ptr [ebp+0x08]
		0xD9, 0xF8,		// fprem
		0xDD, 0x5D, 0xF8,	// fstp qword ptr [ebp-0x08]
		0xDD, 0xD8,		// fstp st(0)
		0xDD, 0x45, 0xF8,	// fld qword ptr [ebp-0x08]
		0x5D,			// pop ebp
		0xC3			// ret
	};
	ptr = machine_code;
	ptr(x, y);
}

void main()
{
	printf("fmod(7.0, 5.0) = %f", fmod_native(7.0, 5.0));
}


Posted By: WretchedSid

Re: Assertion macro - 10/05/10 21:58

But Conitec also offers shader support and they are clearly not easy to use and for beginners. Same goes for Multiplayer, so why no inline assembler?
Users who have no clue about assembler don't need to use it and it wouldn't bother them. But for me it would be really useful as I could improve some functions calls to my runtime.

However, your solution might work but in fact its just a nicer buffer overflow (or at least the same way to use a buffer overflow without the overflow) and it doesn't look like something work with. Finding the hexadecimal for the mnemonics isn't the problem but a official solution would feel much better and safer (I think you can understand this).
However, your solution is really awesome. Hut ab!
Posted By: FlorianP

Re: Assertion macro - 10/06/10 04:23

The lite-C compiler is a pretty lightweight thingy for using the engine - it was never intended to replace 'real' c-compilers.
If you have 'a clue' about assembler then why would you take the limitations of lite-c instead of using f.i. c++?
Mostly because SED lacks basic features that are pretty much standard when developing larger programs
Posted By: WretchedSid

Re: Assertion macro - 10/06/10 06:31

Yeah, SED is really far far behind a real IDE, but this is imo no reason to castrate the compiler...
And for the record: I use a C++ compiler for my library and this isn't a Lite-c only project, in fact its just a port and I don't want to maintain two versions of my library (Once the normal one and then the Lite-C one with dll and extra header).
Even a simple inline assembler would do the trick.

Edit: Und wenn ein inline assembler auf gar keinen Fall rein kommt, wie wäre es mit der Möglichkeit .s files direkt zu kompilieren? Das bisschen um eine Funktion herum is ja jetzt auch kein Hindernis.
Posted By: Joey

Re: Assertion macro - 10/06/10 09:06

Code:
double fmod_native(double x, double y)
{
	double ptr(double,double);
	static char machine_code[] = {
		0x55,			// push ebp
		0x8B, 0xEC,		// mov ebp, esp
		0xDD, 0x45, 0x10,	// fld qword ptr [ebp+0x10]
		0xDD, 0x45, 0x08,	// fld qword ptr [ebp+0x08]
		0xD9, 0xF8,		// fprem
		0xDD, 0x5D, 0xF8,	// fstp qword ptr [ebp-0x08]
		0xDD, 0xD8,		// fstp st(0)
		0xDD, 0x45, 0xF8,	// fld qword ptr [ebp-0x08]
		0x5D,			// pop ebp
		0xC3			// ret
	};
	ptr = machine_code;
	ptr(x, y);
}

void main()
{
	printf("fmod(7.0, 5.0) = %f", fmod_native(7.0, 5.0));
}


this is a security risk and should definitely not work. that's exactly how hackers inject code and execute it. i thought this would be gone with the no execution bit on newer processors...
Posted By: WretchedSid

Re: Assertion macro - 10/06/10 09:18

Thats not a security risk and not the same way hackers inject code into your application.

However, I agree that this isn't the nicest and cleanest solution and that there is a need for an official inline assembler function/macro/what ever.
Posted By: Joey

Re: Assertion macro - 10/06/10 22:03

It is. I'm not sure this works anyway (haven't tested it) since the function is not on the heap when you define it as static variable. I thought you'd have to allocate space on the heap, but I could be mistaken here. Anyway, I don't think the memory page you're writing your data into is marked PAGE_EXECUTE_READWRITE. I think you have to call VirtualProtect to change that.
Implementing this one could even write an own inline assembler.
Posted By: WretchedSid

Re: Assertion macro - 10/07/10 06:47

No it isn't. The memory is accessible for your application and the kernel. There is no way to let user input new commands so every other access would result in an segfault.
What hackers uses are overflows to inject new code, thats why strcpy() is a bad function.
Posted By: Joey

Re: Assertion macro - 10/07/10 14:18

let's ask allmighty wikipedia:
Originally Posted By: http://en.wikipedia.org/wiki/NX_bit
[the nx-bit] is used to prevent certain types of malicious software from taking over computers by inserting their code into another program's data storage area and running their own code from within this section; this is known as a buffer overflow attack.

That's why DATA memory should NOT be allowed to be executed. You say there is no way to let users input new commands? But in your next sentence you tell us how... well, the segmentation fault should occur if you try to execute data memory.
Posted By: WretchedSid

Re: Assertion macro - 10/07/10 14:30

Interesting, you all mighty wiki says its in the last sentence:
Quote:
this is known as a buffer overflow attack.


The posted code is in no case a buffer overflow and also not a stack overflow.
I told you that you can inject new code when you let the user write into the memory by eg. don't check your strings but just use strcpy. That is _NOT_ the case in the sample code.

Segfaults should also not occur when you try to execute something from the heap but only when you try to access unmapped memory.
Posted By: Joey

Re: Assertion macro - 10/07/10 18:10

Of course your code is not a buffer overflow. That's not what I'm talking about. I meant executing data memory. You began talking about how that can be done - via a buffer overflow or whatever. And that's why you shouldn't be able to do it. Simples.
Posted By: WretchedSid

Re: Assertion macro - 10/07/10 18:24

No, you have mistaken me. Your point was that the code is evil because hackers use this to inject new code. I wanted to show you that you are wrong because the code isn't evil, I never wanted to argue about the NX-Bit or the evil heap. (Did you know that you can also have code on the stack and execute it? What about an NX-Bit for the stack?)

And by the way, instead of writing save code without using functions that are clearly marked as evil (like strcpy), you want to prevent anyone from executing something from the heap? Thats like saying "Ouh, my teeth hurts like hell. Lets cut of my head so I don't feel 'em anymore"
Just my 2 cents about the NX-Bit
Posted By: Joey

Re: Assertion macro - 10/07/10 19:33

I don't think it's a good idea neither. I think we have aneinander vorbeigeredet and meant the same thing wink.
Posted By: WretchedSid

Re: Assertion macro - 10/07/10 20:42

Nur weil ich am gewinnen war D:
Posted By: Joey

Re: Assertion macro - 10/07/10 20:57

Hier hast du nen Keks:



wink
© 2024 lite-C Forums