Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc emits different binary code when enabling debuginfo=2 at opt-level=0,2,3 #92737

Closed
theo-lw opened this issue Jan 10, 2022 · 6 comments
Closed
Labels
A-codegen Area: Code generation A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@theo-lw
Copy link
Contributor

theo-lw commented Jan 10, 2022

I tried this compiling this code (mutant_224.rs) with and without debug info:

use std ::path ::PathBuf;
use std ::sync ::Arc;
pub fn a(_b : Arc<String>) {}
pub fn c(_b : Arc<PathBuf>) {}

I expected to see this happen: I expected the .text sections to be same when compiling with and without debug info

Instead, this happened: the .text sections are different. See below on how to recreate the difference.

opt-level=3
$ rustc --emit obj --crate-type lib -C opt-level=3 mutant_224.rs -o temp_compilation_consistency_lib.o
$ objdump -d temp_compilation_consistency_lib.o > no_debug.txt
$ rustc --emit obj --crate-type lib -C opt-level=3 mutant_224.rs -C debuginfo=2 -o temp_compilation_consistency_lib.o
$ objdump -d temp_compilation_consistency_lib.o > debug.txt
$ diff no_debug.txt debug.txt
12a13,20
> Disassembly of section .text._ZN10mutant_2241c17hf79351e63177ef16E:
>
> 0000000000000000 <_ZN10mutant_2241c17hf79351e63177ef16E>:
>    0:	f0 48 83 2f 01       	lock subq $0x1,(%rdi)
>    5:	75 05                	jne    c <_ZN10mutant_2241c17hf79351e63177ef16E+0xc>
>    7:	e9 00 00 00 00       	jmpq   c <_ZN10mutant_2241c17hf79351e63177ef16E+0xc>
>    c:	c3                   	retq
>
34a43,67
>   43:	5b                   	pop    %rbx
>   44:	c3                   	retq
>
> Disassembly of section .text._ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE:
>
> 0000000000000000 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE>:
>    0:	53                   	push   %rbx
>    1:	48 89 fb             	mov    %rdi,%rbx
>    4:	48 8b 77 18          	mov    0x18(%rdi),%rsi
>    8:	48 85 f6             	test   %rsi,%rsi
>    b:	74 14                	je     21 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x21>
>    d:	48 8b 7b 10          	mov    0x10(%rbx),%rdi
>   11:	48 85 ff             	test   %rdi,%rdi
>   14:	74 0b                	je     21 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x21>
>   16:	ba 01 00 00 00       	mov    $0x1,%edx
>   1b:	ff 15 00 00 00 00    	callq  *0x0(%rip)        # 21 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x21>
>   21:	48 83 fb ff          	cmp    $0xffffffffffffffff,%rbx
>   25:	74 1c                	je     43 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x43>
>   27:	f0 48 83 6b 08 01    	lock subq $0x1,0x8(%rbx)
>   2d:	75 14                	jne    43 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x43>
>   2f:	be 28 00 00 00       	mov    $0x28,%esi
>   34:	ba 08 00 00 00       	mov    $0x8,%edx
>   39:	48 89 df             	mov    %rbx,%rdi
>   3c:	5b                   	pop    %rbx
>   3d:	ff 25 00 00 00 00    	jmpq   *0x0(%rip)        # 43 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x43>
opt-level=2
$ rustc --emit obj --crate-type lib -C opt-level=2 mutant_224.rs -o temp_compilation_consistency_lib.o
$ objdump -d temp_compilation_consistency_lib.o > no_debug.txt
$ rustc --emit obj --crate-type lib -C opt-level=2 mutant_224.rs -C debuginfo=2 -o temp_compilation_consistency_lib.o
$ objdump -d temp_compilation_consistency_lib.o > debug.txt
$ diff no_debug.txt debug.txt
16a17,28
> Disassembly of section .text._ZN10mutant_2241c17hf79351e63177ef16E:
>
> 0000000000000000 <_ZN10mutant_2241c17hf79351e63177ef16E>:
>    0:	50                   	push   %rax
>    1:	48 89 3c 24          	mov    %rdi,(%rsp)
>    5:	f0 48 83 2f 01       	lock subq $0x1,(%rdi)
>    a:	75 08                	jne    14 <_ZN10mutant_2241c17hf79351e63177ef16E+0x14>
>    c:	48 89 e7             	mov    %rsp,%rdi
>    f:	e8 00 00 00 00       	callq  14 <_ZN10mutant_2241c17hf79351e63177ef16E+0x14>
>   14:	58                   	pop    %rax
>   15:	c3                   	retq
>
36a49,71
>   3e:	5b                   	pop    %rbx
>   3f:	c3                   	retq
>
> Disassembly of section .text._ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE:
>
> 0000000000000000 <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE>:
>    0:	53                   	push   %rbx
>    1:	48 8b 1f             	mov    (%rdi),%rbx
>    4:	48 8b 73 18          	mov    0x18(%rbx),%rsi
>    8:	48 85 f6             	test   %rsi,%rsi
>    b:	74 0f                	je     1c <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x1c>
>    d:	48 8b 7b 10          	mov    0x10(%rbx),%rdi
>   11:	ba 01 00 00 00       	mov    $0x1,%edx
>   16:	ff 15 00 00 00 00    	callq  *0x0(%rip)        # 1c <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x1c>
>   1c:	48 83 fb ff          	cmp    $0xffffffffffffffff,%rbx
>   20:	74 1c                	je     3e <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x3e>
>   22:	f0 48 83 6b 08 01    	lock subq $0x1,0x8(%rbx)
>   28:	75 14                	jne    3e <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x3e>
>   2a:	be 28 00 00 00       	mov    $0x28,%esi
>   2f:	ba 08 00 00 00       	mov    $0x8,%edx
>   34:	48 89 df             	mov    %rbx,%rdi
>   37:	5b                   	pop    %rbx
>   38:	ff 25 00 00 00 00    	jmpq   *0x0(%rip)        # 3e <_ZN5alloc4sync12Arc$LT$T$GT$9drop_slow17hfdffe63a6a7ce69bE+0x3e>
opt-level=0
$ rustc --emit obj --crate-type lib -C opt-level=0 mutant_224.rs -o temp_compilation_consistency_lib.o
$ objdump -d temp_compilation_consistency_lib.o > no_debug.txt
$ rustc --emit obj --crate-type lib -C opt-level=0 mutant_224.rs -C debuginfo=2 -o temp_compilation_consistency_lib.o
$ objdump -d temp_compilation_consistency_lib.o > debug.txt
$ diff no_debug.txt debug.txt
see attached file

diff.txt

Meta

rustc --version --verbose:

rustc 1.57.0 (f1edd0429 2021-11-29)
binary: rustc
commit-hash: f1edd0429582dd29cccacaf50fd134b05593bd9c
commit-date: 2021-11-29
host: x86_64-unknown-linux-gnu
release: 1.57.0
LLVM version: 13.0.0

This behaviour also exists in the nightly version:

rustc 1.60.0-nightly (092e1c9d2 2022-01-09)
binary: rustc
commit-hash: 092e1c9d23158d81be27bb6f71bdd0c6282478fb
commit-date: 2022-01-09
host: x86_64-unknown-linux-gnu
release: 1.60.0-nightly
LLVM version: 13.0.0

@theo-lw theo-lw added the C-bug Category: This is a bug. label Jan 10, 2022
@theo-lw theo-lw changed the title .text section changes when enabling debuginfo=2 at opt-level=3 .text section changes when enabling debuginfo=2 at opt-level=0,2,3 Jan 10, 2022
@theo-lw theo-lw changed the title .text section changes when enabling debuginfo=2 at opt-level=0,2,3 rustc emits different binary code when enabling debuginfo=2 at opt-level=0,2,3 Jan 11, 2022
@theo-lw
Copy link
Contributor Author

theo-lw commented Jan 12, 2022

@rustbot label: +A-debuginfo +T-compiler +A-codegen

@rustbot rustbot added A-codegen Area: Code generation A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 12, 2022
@bjorn3
Copy link
Member

bjorn3 commented Jan 21, 2022

Variables are spilled to the stack for debuginfo:

Self::spill_operand_to_stack(operand, name, bx)
Also I am not sure LLVM guarantees that adding debuginfo doesn't change the compiled code.

@nagisa
Copy link
Member

nagisa commented Jan 21, 2022

Indeed, this is expected, and I'm pretty sure we don't really have a feasible way forward in changing the implementation here to be different in anyway. If you need a reproducible .text, compile with -Cdebuginfo always, and strip the debug info as a followup step.

Closing as inactionable.

@nagisa nagisa closed this as completed Jan 21, 2022
@chengniansun
Copy link

Hi @bjorn3 and @nagisa

Thank you for taking a look at this issue. Both GCC and LLVM try to make such a compilation consistency wrt debug info. We have found several bugs in GCC which are already fixed, and some bugs in LLVM, which are confirmed for now.

The rational behind this issue is that if a developer wants to debug a binary which has no debug info, then the developer can recompile the program with debug info, and the compiler, e.g., gcc or llvm, guarantees that the binary code will be the same.

Since rustc currently does not support this guarantee, we will stop testing rustc.

Thank you for your time.

@bjorn3
Copy link
Member

bjorn3 commented Jan 21, 2022

I knew GCC does this. I didn't know LLVM does too. I agree it would be nice if rustc has the same guarantee, but this isn't the case currently. There is an open issue to use llvm.dbg.define instead of llvm.dbg.declare which allows avoiding the stack spilling, however it seems that LLVM is too eager to forget about the local when using llvm.dbg.define, forgetting it as soon as it is no longer used rather than once it goes out of scope.

@nagisa
Copy link
Member

nagisa commented Jan 21, 2022

A possibly good idea would be to submit a MCP or RFC to establish a need for such guarantee. I feel once the developers come to a consensus it is a good idea to guarantee this kind of property, then they are much more likely to implement the support necessary on the rustc side as well as petition for the fixes necessary on the LLVM side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-codegen Area: Code generation A-debuginfo Area: Debugging information in compiled programs (DWARF, PDB, etc.) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants