I have something like this in my code that checks for user's license:
// C# code:
#if DEBUG
MakeLicenseValidForever();
#else
CheckLicense();
#endif
Now, I need to know if these directives get saved in my released binary or not. If they do get saved, then a user can make #if DEBUG return true and bypass the checks. I need to know if #if DEBUG is safe.
PS1: Obviously I use release mode for distribution.
PS2: I asked my question here first, but since it's not getting any attention, I ask it here again!
No, preprocessor directives are processed at compile time, namely, the compiler won't compile the section into the resulting binary. It's more like code comments, which are discarded during compilation, you can even put invalid statement there and the compiler won't complain about it.
In general, however, your code would be compiled to intermediate language(IL), which isn't native machine code and be decompiled pretty easily. If you want protection better use some AOT compilation technology or obfuscator.
C# is a language which is compiled into byte code, eg your statements are getting processed during compilation.
Conditional statements, used by compiler, are accessable and compilable only if they are defined. In another words, compiler do not see any other statements and your code is safe
Related
In C/C++ we've had
#ifdef _DEBUG
...
#endif
In C# we've got
#if DEBUG
...
#endif
and
[Conditional("DEBUG")]
I don't expect anything as fancy as an attribute based way of dealing with debug only code but would like to know if there's a manifest constant kind of thing or any other way of making code only present in a debug build. For instance I'm doing the following in Lua at the moment:
if not type(parameters.callback) == 'function' then
error('The "callback" parameter is not a function, or missing (nil).');
end
if not type(parameters.times) == 'number' then
error('The "times" parameter is not a number or missing (nil).');
end
if not type(parameters.interval) == 'number' or not parameters.interval == nil then
error('The "interval" parameter is not a number.');
end
I don't even know if that will run. Totally new to the language.
Given the nature of the function I'm writing, a simple retry function taking the number of attempts to make, an optional interval and a callback as parameters - which I anticipate being used many times throughout the application being written - and that its to be run on a micro controller I feel these checks should not be made in a production release as I'm guessing they could be relatively costly?!?! I'm even doing a type check within a for loop.
Is there already something built into the language to allow for conditional compilation? Or has anyone come up with a neat and clean way of handling this sort of thing? I know I could declare a global variable marking it a debug build and simply put and if block around the above but I thought I'd ask.
Googling has got me nowhere. In fact when I read the sites that talk about Lua I feel like I've stepped back to the mid to late 90's web.
Thanks,
Lee.
EDIT
Or perhaps I just write the method as a C module?!?!
way of making code only present in a debug build
There is no "build" for Lua. It's an interpreted language. Internally it is compiled to byte code, but that's an implementation detail.
However, if you're OK with having a build step, then you can just use a precompiler, exactly as C does. In fact, you can use the same one your your C compiler does, then you're getting the exactly syntax you're already familiar with.
For instance, my old copy of MSVC uses cl /EP <filename> to run filename through the preprocessor and dump the output to stdout. Then you can write:
#ifdef _DEBUG
-- debug Lua code goes here
#endif
The cleanest way would probably be something like
_DEBUG = true
if _DEBUG then
--code
end
The flavour of Lua being used is eLua or Embedded Lua and it does allow pre-compiling scripts to bytecode.
The code is on GitHub so if time permits I'll see about submitting a patch that will allow for true conditional compilation as it's all C under the hood.
In that way everyone benefits. Whether the checks in the original question are costly or not there are often times when you want code in or out depending upon whether you're actively working on it or its being used in a production environment but not the other way around.
And since they support pre-compilation and only target embedded devices with differing levels of performance and memory constraints I wouldn't be surprised if they haven't already implemented support. I'll hop along there and find out next.
Thanks all.
I have decompiled C# dll and now can not compile it. It shows strange errors, for example in some switch blocks some case blocks havent their break statements, or errors like "Can not cast int to bool" are shown. But the amount of errors is not very large for dll of that size, so I think it is not the problem of decompiler.
Is there some derective for compiler (for example, smthing life unsafe) that will solve this problem? Or why is there such strange errors?
P.S. The dll is not broken - the application is using it right now. I'm using dotPeek to decompile and Visual Studio 15 to compile the result code.
For such an error like :
"Can not cast int to bool"
There is absolutely no compiler directive that will allow your compiler to go ahead, I think that your decompiler messed up something decompiling ... You could simply try with another decompiler and see if you get another results, valid alternatives are : ILSpy, JustDecompile and Dotnet IL Editor .
Be aware that some commercial DLL is obfuscated just to try to make life difficult to the decompiler and to who decompile ...
Be careful to avoid breaking some copyright .
It's quite hard to decompile IL to C# and decompiler has probably done something wrong. In my experience, decompiled and compiled code can also behave differently than original assembly, so be aware. And such compile error can be indocation that dotPeek was not sure, so think about it what it should do or look in IL.
If you are willing to make really small edits to the assembly (inject method calls, make something public) it may be safer to do it directly in IL obtained by ildasm.
I have an application and I will have two versions - Trial and Commercial. The trial will have some limited features compared to the Commercial version.However I need to make it so that when one has the trial version, it will be impossible for him to uncover the features in the full version. The simplest idea is to have two absolutely separate builds, however this will be hard to maintain(I think). The second idea I have is to build the solutions with a Conditional Compilation Symbols - Trial and Full. I will adapt the source to work this way and I will use #If statements. My question is if this is safe. As it seems the code which is not in the Full compilation symbol's #If statement will be excluded from the assembly but I need your help on this as I need to be sure. Thanks a lot
You are correct code excluded via conditional compilation will not be included in the resulting executable. In that way it is 'safe', i.e. it can't be hacked to execute code that isn't there. All managed code by it's nature is decompilable.
You cannot use conditional compilation to produce a single executable file that contains both states (defined/undefined) of your code and select behavior at runtime.
In C#, we have 2 modes to build projects : Debug and Release, I wonder if Java has the same thing. I am using IntelliJ IDEA as Java IDE and so far I haven't seen anywhere to configure a build mode like in VS IDE.
javac
-g Generate all debugging info
-g:none Generate no debugging info
-g:{lines,vars,source} Generate only some debugging info
You can choose to include debug symbols in the compiled classes (this is the default) or to not do so. There is not much benefit to not doing that. The jar files will be a little smaller, but the performance benefit is minimal (if any). Without these symbols you no longer get line numbers in stack traces. You also have the option to include additional symbols with local variable names (by default there are only source file names and line numbers).
java
-ea[:<packagename>...|:<classname>]
-enableassertions[:<packagename>...|:<classname>]
enable assertions
You can also enable assertions at run-time (default is off), which is sometimes useful during development and testing. This does have a performance impact (if the code in question did indeed make use of assertions, which I think is uncommon).
Regardless of any of these settings, the JVM always allows you to attach a debugger.
What Java does not have is conditional compilation where completely different code would be compiled based on some external setting. The closest you can get is something like public static final boolean DEBUG_BUILD = true; somewhere in your code and use that in if statements. This will actually make the compiler exclude code that becomes unreachable, but you have to set this constant in the source code.
It is normal practice in Java to release everything is a manner which can be debugged. For some projects requiring obfuscation, they could have a release build, but I have never seen this in 12 years of developing Java.
Things such as assertions and debug messages are usually turned off at runtime for a production instance but can be turned on at any time (even dynamically) if required.
IMHO it is best practice to use the same build in every environment, not just the same source but the same JARs. This gives you the best chance that, if it works in test, it will work in production and if you have a problem in production, you can re-produce it in test.
As so much Java code is written this way, the JIT is very good at optimising dead code which is never called. So much so that IMHO most of the micro-"benchmarks" where Java out performs C++, is when the benchmark doesn't do any thing and the JIT is better at detecting this. IMHO, C++ assumes the developer is smart enough not to write code which doesn't do anything.
You're asking for different kinds of builds to compile in different things I guess. For example to have Debug.WriteLine and Console.WriteLine.
"No, Java doesn't have an exact match for that functionality. You could use aspects, or use an IOC container to inject different implementation classes." stole this from the following question: Conditional Java compilation
(there're other nice answers for you there)
So Jeff Atwood rightly complained about Visual Studio not performing background compilation see: http://www.codinghorror.com/blog/2007/05/c-and-the-compilation-tax.html
The solution from most sources seems to be Reshaper which will incrementally perform background compilation as you write. This leads to their great realtime re-factoring tips and error detection.
But what I don't understand is with R# continually compiling my code, why does it take so long when executing a compilation via VS (i.e. Ctrl + Shift + B or similar). What I mean by this is, if R# has already compiled my code then why would I need a recompilation?
My assumption is of course that R# is not overriding the assemblies in my bin directories but instead holding the compilation results in memory. In which case, is it possible to tell R# to simply override my assemblies when compilation is successful?
I don't know about "rightly complained" - that's an opinion I happen to disagree with:)
However, the VB.NET (and probably Resharper c#) background compilers do not actually compile full assemblies - they cannot! If you think about it, the natural state of your code while you are working is not compilable! Almost every keystroke puts your code in an invalid state. Think of this line:
var x = new Something();
As you type this, from the key "v" to the key ")", your code is "wrong". Or what if you are referencing a method you haven't defined yet? And if this code is in an assembly that another assembly requires, how would you compile that second assembly at all, background or not?
The background compilers get around this by compiling small chunks of your code into multiple transient "assemblies" that are actually just metadata holders - really, they don't care about the actual effects of the code as much as the symbols defined, used, etc. When you finally hit build, the actual full assemblies still need to be built.
So no, I don't believe it's possible because they're not built to do actual full compilation - they are built to check your code and interpret symbols on the fly.
Reshaper which will incrementally perform background compilation as you write
It doesn't, it just parses the source code. The exact same thing Visual Studio already does if you don't have Resharper, that's how it implements IntelliSense, its own refactoring features and commands like GoTo Definition and Find All References. Visual Studio also parses in the background, updating its data while you type. Resharper just implements more bells and whistles with that parsing data.
Going from parsing the code to actually generating the assembly is a pretty major step. The internal format of an assembly is too convoluted to allow this to happen in the background without affecting the responsiveness of the machine.
And the C# compiler is still a large chunk of unmanaged C++ code that is independent from the IDE. An inevitable consequence of having to have the compiler first. It is however a stated goal for the next version of C# to provide compile-on-demand services. Getting true background compilation is a possibility.
I don't really have an answer but I just wanted to say that I have been using Eclipse and Java for 4 months now and I love the automatic compilation. I have a very large java code base and compilation happens constantly as I save code changes. When I hit Run everything is ready to go! It's just awesome. It also deploys to the local web server instance (Tomcat in my case) automatically as I make code changes. All this is setup by default in Eclipse.
I hope Microsoft does something similar with .net in the near future.