debug vs. release in C#


A question came up on an internal DL about checking if an assembly was debug or release.  I’m always looking for something to spout about, and this seemed like a good one.


 


There are 3 things people typically identify as the difference between debug & release.  You need to decide which one you’re interested in:


 


“DEBUG” preprocessor flag. Can be set on the whole assembly/netmodule with ‘csc /define’, or on a whole file with #define. 


 


Debugging information (pdb).  Set with ‘csc /debug[+|-]’.   It doesn’t affect codegen, so it’s really not very interesting.


 


Optimization.  Set with ‘csc /optimize[+|-]’.  In managed code, the JITter in the runtime does nearly all the optimization.  The difference in generated IL from this flag is pretty small.  The Whidbey C# compiler has more a difference on this flag than previous versions, but it’s still not much.


 


I don’t know of a way to ask what preprocessor flags were set for compiling a bit of code, but I would start my search by thinking about how they are applied at the file and assembly/netmodule scopes. 


 

Comments (2)

  1. Jay — actually the /debug+ switch does have a significant effect on the code that is generated… While the /optimize[+|-] switch controls C# optimizations, the /debug[+|-] switch controls JIT optimizations (if you compile with /debug+ you’ll see a funny attribute on your assembly that is commented out which indicates that the JIT should generate debuggable code. Disabling JIT optimizations is very useful for debugging purposes but will very much affect the runtime perf of an app as much of the optmization of your code is done by the JIT, not CSC (for a number of reasons, including that the JIT needs fairly non-optmized IL as input to allow it to execute quickly).

    If what you really want to do is just get PDBs then the /debug:pdbonly switch is what you’re looking for. Below I’ve included some output from a native debugger (windbg, on AMD64 – but the principal holds on all platforms) of a simple whidbey app compiled with and without the /debug+ switch (and also with /debug-). It is of note that if you’re running under the VS debugger I believe that you will always see debuggable code unless you attach to the process and the code you’re interested in has already been JIT’ed.

    csc /out:t1.exe t1.cs

    ——————————————–

    0:000> !u 000007ff`ff1f0660

    Normal JIT generated code

    Test.Main()

    Begin 000007ffff1f0660, size 26

    sub rsp,0x28

    mov rcx,0x7fff71c3030

    mov rcx,[rcx]

    mov rax,0x5cc00bf0

    mov rax,[rax]

    call rax (System.Console.WriteLine(System.String), mdToken: 06000788)

    nop

    add rsp,0x28

    ret

    csc /debug- /out:t1-debug-.exe t1.cs

    ——————————————-

    0:000> !u 000007ff`ff1d0660

    Normal JIT generated code

    Test.Main()

    Begin 000007ffff1d0660, size 26

    sub rsp,0x28

    mov rcx,0x7fff71c3030

    mov rcx,[rcx]

    mov rax,0x5cc00bf0

    mov rax,[rax]

    call rax (System.Console.WriteLine(System.String), mdToken: 06000788)

    nop

    add rsp,0x28

    ret

    csc /debug+ /out:t1-debug+.exe t1.cs

    ——————————————–

    0:000> !u 000007ff`ff1d0660

    Normal JIT generated code

    Test.Main()

    Begin 000007ffff1d0660, size 5c

    sub rsp,0x38

    jmp t1_debug_!Test.Main()+0xd (000007ffff1d066d)

    lea ebx,[rbx]

    mov rcx,0x7ffffe784e8

    mov ecx,[rcx]

    mov rax,0x5f095098 (JitHelp: CORINFO_HELP_DBG_IS_JUST_MY_CODE)

    mov [rsp+0x20],rax

    test ecx,ecx

    jz t1_debug_!Test.Main()+0x30 (000007ffff1d0690)

    call qword ptr [rsp+0x20]

    mov rcx,0x7fff71c3030

    mov rcx,[rcx]

    mov rax,0x5cc00bf0

    mov rax,[rax]

    call rax (System.Console.WriteLine(System.String), mdToken: 06000788)

    jmp t1_debug_!Test.Main()+0x55 (000007ffff1d06b5)

    lea ebx,[rbx]

    jmp t1_debug_!Test.Main()+0x57 (000007ffff1d06b7)

    add rsp,0x38

    ret

  2. jaybaz [MS] says:

    Ahh, you’re right about that, Josh. I do mean that pdbonly should be the default, and that /debug- should be impossible.

    I’m glad smart people read my blog, to balance me out. 🙂

Skip to main content