Strange looping at end of function body call C++

2020-04-16 01:46发布

问题:

I am writing a game program in C++ and have encountered an odd problem that seems to be unique to this function.

When this function is called, it executes just as expected all the way through to the return statement. However, upon executing the return statement, the code 'jumps' up two lines to the constructor and executes the code between the constructor and the return statement again. What's more, when I check the value passed to the FileManager constructor on the second iteration, it has the value of 'level_directory' prepended to it (but only inside the constructor, when I check the function call everything is fine).

Relevant info:

Debugger: GDB 7.6-1
OS: Arch Linux x86_64
IDE: Code::Blocks 12.11

g++ -S -masm=intel main.cpp;cat main.s | c++filt > disasm.s

In file included from game.h:9:0,
                 from main.cpp:4:
playstate.h:32:45: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default]
         const std::string level_directory = "data/levels/";

    .file   "main.cpp"
    .intel_syntax noprefix
    .text
    .globl  main
    .type   main, @function
main:
.LFB1826:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    .cfi_lsda 0x3,.LLSDA1826
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    push    rbx
    sub rsp, 552
    .cfi_offset 3, -24
    lea rax, [rbp-560]
    mov rdi, rax
.LEHB0:
    call    _ZN4GameC1Ev
.LEHE0:
    jmp .L2
.L3:
    lea rax, [rbp-560]
    mov rdi, rax
.LEHB1:
    call    _ZN4Game12HandleEventsEv
    lea rax, [rbp-560]
    mov rdi, rax
    call    _ZN4Game6UpdateEv
    lea rax, [rbp-560]
    mov rdi, rax
    call    _ZN4Game6RenderEv
.L2:
    lea rax, [rbp-560]
    mov rdi, rax
    call    _ZN4Game9isRunningEv
.LEHE1:
    test    al, al
    jne .L3
    lea rax, [rbp-560]
    mov rdi, rax
.LEHB2:
    call    _ZN4GameD1Ev
.LEHE2:
    mov eax, 0
    jmp .L9
.L8:
    mov rbx, rax
    lea rax, [rbp-560]
    mov rdi, rax
    call    _ZN4GameD1Ev
    mov rax, rbx
    jmp .L6
.L7:
.L6:
    mov rdi, rax
.LEHB3:
    call    _Unwind_Resume
.LEHE3:
.L9:
    add rsp, 552
    pop rbx
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1826:
    .globl  __gxx_personality_v0
    .section    .gcc_except_table,"a",@progbits
.LLSDA1826:
    .byte   0xff
    .byte   0xff
    .byte   0x1
    .uleb128 .LLSDACSE1826-.LLSDACSB1826
.LLSDACSB1826:
    .uleb128 .LEHB0-.LFB1826
    .uleb128 .LEHE0-.LEHB0
    .uleb128 .L7-.LFB1826
    .uleb128 0
    .uleb128 .LEHB1-.LFB1826
    .uleb128 .LEHE1-.LEHB1
    .uleb128 .L8-.LFB1826
    .uleb128 0
    .uleb128 .LEHB2-.LFB1826
    .uleb128 .LEHE2-.LEHB2
    .uleb128 .L7-.LFB1826
    .uleb128 0
    .uleb128 .LEHB3-.LFB1826
    .uleb128 .LEHE3-.LEHB3
    .uleb128 0
    .uleb128 0
.LLSDACSE1826:
    .text
    .size   main, .-main
    .ident  "GCC: (GNU) 4.8.0 20130502 (prerelease)"
    .section    .note.GNU-stack,"",@progbits
                                         ^

and for playstate.cpp

    .file   "playstate.cpp"
    .intel_syntax noprefix
    .section    .text._ZN5StateC2Ev,"axG",@progbits,_ZN5StateC5Ev,comdat
    .align 2
    .weak   _ZN5StateC2Ev
    .type   _ZN5StateC2Ev, @function
_ZN5StateC2Ev:
.LFB1:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    mov rax, QWORD PTR [rbp-8]
    mov QWORD PTR [rax], OFFSET FLAT:_ZTV5State+16
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1:
    .size   _ZN5StateC2Ev, .-_ZN5StateC2Ev
    .weak   _ZN5StateC1Ev
    .set    _ZN5StateC1Ev,_ZN5StateC2Ev
    .section    .text._ZN5StateD2Ev,"axG",@progbits,_ZN5StateD5Ev,comdat
    .align 2
    .weak   _ZN5StateD2Ev
    .type   _ZN5StateD2Ev, @function
_ZN5StateD2Ev:
.LFB4:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    sub rsp, 16
    mov QWORD PTR [rbp-8], rdi
    mov rax, QWORD PTR [rbp-8]
    mov QWORD PTR [rax], OFFSET FLAT:_ZTV5State+16
    mov eax, 0
    test    eax, eax
    je  .L2
    mov rax, QWORD PTR [rbp-8]
    mov rdi, rax
    call    _ZdlPv
.L2:
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE4:
    .size   _ZN5StateD2Ev, .-_ZN5StateD2Ev
    .weak   _ZN5StateD1Ev
    .set    _ZN5StateD1Ev,_ZN5StateD2Ev
    .section    .text._ZN5StateD0Ev,"axG",@progbits,_ZN5StateD0Ev,comdat
    .align 2
    .weak   _ZN5StateD0Ev
    .type   _ZN5StateD0Ev, @function
_ZN5StateD0Ev:
.LFB6:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    sub rsp, 16
    mov QWORD PTR [rbp-8], rdi
    mov rax, QWORD PTR [rbp-8]
    mov rdi, rax
    call    _ZN5StateD1Ev
    mov rax, QWORD PTR [rbp-8]
    mov rdi, rax
    call    _ZdlPv
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE6:
    .size   _ZN5StateD0Ev, .-_ZN5StateD0Ev
    .section    .rodata
.LC0:
    .string "data/levels/"
    .text
    .align 2
    .globl  _ZN9PlayStateC2Ev
    .type   _ZN9PlayStateC2Ev, @function
_ZN9PlayStateC2Ev:
.LFB1043:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    .cfi_lsda 0x3,.LLSDA1043
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    push    rbx
    sub rsp, 40
    .cfi_offset 3, -24
    mov QWORD PTR [rbp-40], rdi
    mov rax, QWORD PTR [rbp-40]
    mov rdi, rax
    call    _ZN5StateC2Ev
    mov rax, QWORD PTR [rbp-40]
    mov QWORD PTR [rax], OFFSET FLAT:_ZTV9PlayState+16
    lea rax, [rbp-17]
    mov rdi, rax
    call    _ZNSaIcEC1Ev
    mov rax, QWORD PTR [rbp-40]
    lea rcx, [rax+8]
    lea rax, [rbp-17]
    mov rdx, rax
    mov esi, OFFSET FLAT:.LC0
    mov rdi, rcx
.LEHB0:
    call    _ZNSsC1EPKcRKSaIcE
.LEHE0:
    lea rax, [rbp-17]
    mov rdi, rax
    call    _ZNSaIcED1Ev
    jmp .L10
.L9:
    mov rbx, rax
    lea rax, [rbp-17]
    mov rdi, rax
    call    _ZNSaIcED1Ev
    mov rax, QWORD PTR [rbp-40]
    mov rdi, rax
    call    _ZN5StateD2Ev
    mov rax, rbx
    mov rdi, rax
.LEHB1:
    call    _Unwind_Resume
.LEHE1:
.L10:
    add rsp, 40
    pop rbx
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1043:
    .globl  __gxx_personality_v0
    .section    .gcc_except_table,"a",@progbits
.LLSDA1043:
    .byte   0xff
    .byte   0xff
    .byte   0x1
    .uleb128 .LLSDACSE1043-.LLSDACSB1043
.LLSDACSB1043:
    .uleb128 .LEHB0-.LFB1043
    .uleb128 .LEHE0-.LEHB0
    .uleb128 .L9-.LFB1043
    .uleb128 0
    .uleb128 .LEHB1-.LFB1043
    .uleb128 .LEHE1-.LEHB1
    .uleb128 0
    .uleb128 0
.LLSDACSE1043:
    .text
    .size   _ZN9PlayStateC2Ev, .-_ZN9PlayStateC2Ev
    .globl  _ZN9PlayStateC1Ev
    .set    _ZN9PlayStateC1Ev,_ZN9PlayStateC2Ev
    .align 2
    .globl  _ZN9PlayStateD2Ev
    .type   _ZN9PlayStateD2Ev, @function
_ZN9PlayStateD2Ev:
.LFB1046:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    .cfi_lsda 0x3,.LLSDA1046
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    push    rbx
    sub rsp, 24
    .cfi_offset 3, -24
    mov QWORD PTR [rbp-24], rdi
    mov rax, QWORD PTR [rbp-24]
    mov QWORD PTR [rax], OFFSET FLAT:_ZTV9PlayState+16
    mov rax, QWORD PTR [rbp-24]
    add rax, 8
    mov rdi, rax
.LEHB2:
    call    _ZNSsD1Ev
.LEHE2:
    mov rax, QWORD PTR [rbp-24]
    mov rdi, rax
    call    _ZN5StateD2Ev
    mov eax, 0
    test    eax, eax
    je  .L16
    mov rax, QWORD PTR [rbp-24]
    mov rdi, rax
    call    _ZdlPv
    jmp .L16
.L15:
    mov rbx, rax
    mov rax, QWORD PTR [rbp-24]
    mov rdi, rax
    call    _ZN5StateD2Ev
    mov rax, rbx
    mov rdi, rax
.LEHB3:
    call    _Unwind_Resume
.LEHE3:
.L16:
    add rsp, 24
    pop rbx
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1046:
    .section    .gcc_except_table
.LLSDA1046:
    .byte   0xff
    .byte   0xff
    .byte   0x1
    .uleb128 .LLSDACSE1046-.LLSDACSB1046
.LLSDACSB1046:
    .uleb128 .LEHB2-.LFB1046
    .uleb128 .LEHE2-.LEHB2
    .uleb128 .L15-.LFB1046
    .uleb128 0
    .uleb128 .LEHB3-.LFB1046
    .uleb128 .LEHE3-.LEHB3
    .uleb128 0
    .uleb128 0
.LLSDACSE1046:
    .text
    .size   _ZN9PlayStateD2Ev, .-_ZN9PlayStateD2Ev
    .globl  _ZN9PlayStateD1Ev
    .set    _ZN9PlayStateD1Ev,_ZN9PlayStateD2Ev
    .align 2
    .globl  _ZN9PlayStateD0Ev
    .type   _ZN9PlayStateD0Ev, @function
_ZN9PlayStateD0Ev:
.LFB1048:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    sub rsp, 16
    mov QWORD PTR [rbp-8], rdi
    mov rax, QWORD PTR [rbp-8]
    mov rdi, rax
    call    _ZN9PlayStateD1Ev
    mov rax, QWORD PTR [rbp-8]
    mov rdi, rax
    call    _ZdlPv
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1048:
    .size   _ZN9PlayStateD0Ev, .-_ZN9PlayStateD0Ev
    .align 2
    .globl  _ZN9PlayState5EnterEv
    .type   _ZN9PlayState5EnterEv, @function
_ZN9PlayState5EnterEv:
.LFB1049:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1049:
    .size   _ZN9PlayState5EnterEv, .-_ZN9PlayState5EnterEv
    .align 2
    .globl  _ZN9PlayState5LeaveEv
    .type   _ZN9PlayState5LeaveEv, @function
_ZN9PlayState5LeaveEv:
.LFB1050:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1050:
    .size   _ZN9PlayState5LeaveEv, .-_ZN9PlayState5LeaveEv
    .align 2
    .globl  _ZN9PlayState6ResumeEv
    .type   _ZN9PlayState6ResumeEv, @function
_ZN9PlayState6ResumeEv:
.LFB1051:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1051:
    .size   _ZN9PlayState6ResumeEv, .-_ZN9PlayState6ResumeEv
    .align 2
    .globl  _ZN9PlayState5PauseEv
    .type   _ZN9PlayState5PauseEv, @function
_ZN9PlayState5PauseEv:
.LFB1052:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1052:
    .size   _ZN9PlayState5PauseEv, .-_ZN9PlayState5PauseEv
    .align 2
    .globl  _ZN9PlayState12HandleEventsEv
    .type   _ZN9PlayState12HandleEventsEv, @function
_ZN9PlayState12HandleEventsEv:
.LFB1053:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1053:
    .size   _ZN9PlayState12HandleEventsEv, .-_ZN9PlayState12HandleEventsEv
    .align 2
    .globl  _ZN9PlayState6UpdateEv
    .type   _ZN9PlayState6UpdateEv, @function
_ZN9PlayState6UpdateEv:
.LFB1054:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1054:
    .size   _ZN9PlayState6UpdateEv, .-_ZN9PlayState6UpdateEv
    .align 2
    .globl  _ZN9PlayState6RenderEv
    .type   _ZN9PlayState6RenderEv, @function
_ZN9PlayState6RenderEv:
.LFB1055:
    .cfi_startproc
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    mov QWORD PTR [rbp-8], rdi
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1055:
    .size   _ZN9PlayState6RenderEv, .-_ZN9PlayState6RenderEv
    .align 2
    .globl  _ZN9PlayState9LoadLevelESs
    .type   _ZN9PlayState9LoadLevelESs, @function
_ZN9PlayState9LoadLevelESs:
.LFB1056:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    .cfi_lsda 0x3,.LLSDA1056
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    push    rbx
    sub rsp, 600
    .cfi_offset 3, -24
    mov QWORD PTR [rbp-600], rdi
    mov QWORD PTR [rbp-608], rsi
    mov rax, QWORD PTR [rbp-600]
    lea rcx, [rax+8]
    lea rax, [rbp-48]
    mov rdx, QWORD PTR [rbp-608]
    mov rsi, rcx
    mov rdi, rax
.LEHB4:
    call    _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_
.LEHE4:
    lea rcx, [rbp-48]
    lea rax, [rbp-592]
    mov edx, 114
    mov rsi, rcx
    mov rdi, rax
.LEHB5:
    call    _ZN11FileManagerC1ERKSsc
.LEHE5:
    lea rax, [rbp-32]
    lea rcx, [rbp-592]
    mov edx, 32
    mov rsi, rcx
    mov rdi, rax
.LEHB6:
    call    _ZN11FileManager14ReadLineStringEc
    lea rax, [rbp-32]
    mov rdi, rax
    call    _ZNSsD1Ev
.LEHE6:
    nop
    lea rax, [rbp-592]
    mov rdi, rax
.LEHB7:
    call    _ZN11FileManagerD1Ev
.LEHE7:
    lea rax, [rbp-48]
    mov rdi, rax
.LEHB8:
    call    _ZNSsD1Ev
.LEHE8:
    jmp .L34
.L33:
    mov rbx, rax
    lea rax, [rbp-592]
    mov rdi, rax
    call    _ZN11FileManagerD1Ev
    jmp .L29
.L32:
    mov rbx, rax
.L29:
    lea rax, [rbp-48]
    mov rdi, rax
    call    _ZNSsD1Ev
    mov rax, rbx
    jmp .L30
.L31:
.L30:
    mov rdi, rax
.LEHB9:
    call    _Unwind_Resume
.LEHE9:
.L34:
    add rsp, 600
    pop rbx
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1056:
    .section    .gcc_except_table
.LLSDA1056:
    .byte   0xff
    .byte   0xff
    .byte   0x1
    .uleb128 .LLSDACSE1056-.LLSDACSB1056
.LLSDACSB1056:
    .uleb128 .LEHB4-.LFB1056
    .uleb128 .LEHE4-.LEHB4
    .uleb128 .L31-.LFB1056
    .uleb128 0
    .uleb128 .LEHB5-.LFB1056
    .uleb128 .LEHE5-.LEHB5
    .uleb128 .L32-.LFB1056
    .uleb128 0
    .uleb128 .LEHB6-.LFB1056
    .uleb128 .LEHE6-.LEHB6
    .uleb128 .L33-.LFB1056
    .uleb128 0
    .uleb128 .LEHB7-.LFB1056
    .uleb128 .LEHE7-.LEHB7
    .uleb128 .L32-.LFB1056
    .uleb128 0
    .uleb128 .LEHB8-.LFB1056
    .uleb128 .LEHE8-.LEHB8
    .uleb128 .L31-.LFB1056
    .uleb128 0
    .uleb128 .LEHB9-.LFB1056
    .uleb128 .LEHE9-.LEHB9
    .uleb128 0
    .uleb128 0
.LLSDACSE1056:
    .text
    .size   _ZN9PlayState9LoadLevelESs, .-_ZN9PlayState9LoadLevelESs
    .section    .text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_,"axG",@progbits,_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_,comdat
    .weak   _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_
    .type   _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_, @function
_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_:
.LFB1069:
    .cfi_startproc
    .cfi_personality 0x3,__gxx_personality_v0
    .cfi_lsda 0x3,.LLSDA1069
    push    rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    mov rbp, rsp
    .cfi_def_cfa_register 6
    push    rbx
    sub rsp, 40
    .cfi_offset 3, -24
    mov QWORD PTR [rbp-24], rdi
    mov QWORD PTR [rbp-32], rsi
    mov QWORD PTR [rbp-40], rdx
    mov rdx, QWORD PTR [rbp-32]
    mov rax, QWORD PTR [rbp-24]
    mov rsi, rdx
    mov rdi, rax
.LEHB10:
    call    _ZNSsC1ERKSs
.LEHE10:
    mov rdx, QWORD PTR [rbp-40]
    mov rax, QWORD PTR [rbp-24]
    mov rsi, rdx
    mov rdi, rax
.LEHB11:
    call    _ZNSs6appendERKSs
.LEHE11:
    jmp .L39
.L38:
    mov rbx, rax
    mov rax, QWORD PTR [rbp-24]
    mov rdi, rax
    call    _ZNSsD1Ev
    mov rax, rbx
    mov rdi, rax
.LEHB12:
    call    _Unwind_Resume
.LEHE12:
.L39:
    mov rax, QWORD PTR [rbp-24]
    add rsp, 40
    pop rbx
    pop rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE1069:
    .section    .gcc_except_table
.LLSDA1069:
    .byte   0xff
    .byte   0xff
    .byte   0x1
    .uleb128 .LLSDACSE1069-.LLSDACSB1069
.LLSDACSB1069:
    .uleb128 .LEHB10-.LFB1069
    .uleb128 .LEHE10-.LEHB10
    .uleb128 0
    .uleb128 0
    .uleb128 .LEHB11-.LFB1069
    .uleb128 .LEHE11-.LEHB11
    .uleb128 .L38-.LFB1069
    .uleb128 0
    .uleb128 .LEHB12-.LFB1069
    .uleb128 .LEHE12-.LEHB12
    .uleb128 0
    .uleb128 0
.LLSDACSE1069:
    .section    .text._ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_,"axG",@progbits,_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_,comdat
    .size   _ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_, .-_ZStplIcSt11char_traitsIcESaIcEESbIT_T0_T1_ERKS6_S8_
    .weak   _ZTV9PlayState
    .section    .rodata._ZTV9PlayState,"aG",@progbits,_ZTV9PlayState,comdat
    .align 32
    .type   _ZTV9PlayState, @object
    .size   _ZTV9PlayState, 88
_ZTV9PlayState:
    .quad   0
    .quad   _ZTI9PlayState
    .quad   _ZN9PlayStateD1Ev
    .quad   _ZN9PlayStateD0Ev
    .quad   _ZN9PlayState5EnterEv
    .quad   _ZN9PlayState5LeaveEv
    .quad   _ZN9PlayState5PauseEv
    .quad   _ZN9PlayState6ResumeEv
    .quad   _ZN9PlayState12HandleEventsEv
    .quad   _ZN9PlayState6UpdateEv
    .quad   _ZN9PlayState6RenderEv
    .weak   _ZTV5State
    .section    .rodata._ZTV5State,"aG",@progbits,_ZTV5State,comdat
    .align 32
    .type   _ZTV5State, @object
    .size   _ZTV5State, 88
_ZTV5State:
    .quad   0
    .quad   _ZTI5State
    .quad   _ZN5StateD1Ev
    .quad   _ZN5StateD0Ev
    .quad   __cxa_pure_virtual
    .quad   __cxa_pure_virtual
    .quad   __cxa_pure_virtual
    .quad   __cxa_pure_virtual
    .quad   __cxa_pure_virtual
    .quad   __cxa_pure_virtual
    .quad   __cxa_pure_virtual
    .weak   _ZTI9PlayState
    .section    .rodata._ZTI9PlayState,"aG",@progbits,_ZTI9PlayState,comdat
    .align 16
    .type   _ZTI9PlayState, @object
    .size   _ZTI9PlayState, 24
_ZTI9PlayState:
    .quad   _ZTVN10__cxxabiv120__si_class_type_infoE+16
    .quad   _ZTS9PlayState
    .quad   _ZTI5State
    .weak   _ZTS9PlayState
    .section    .rodata._ZTS9PlayState,"aG",@progbits,_ZTS9PlayState,comdat
    .type   _ZTS9PlayState, @object
    .size   _ZTS9PlayState, 11
_ZTS9PlayState:
    .string "9PlayState"
    .weak   _ZTS5State
    .section    .rodata._ZTS5State,"aG",@progbits,_ZTS5State,comdat
    .type   _ZTS5State, @object
    .size   _ZTS5State, 7
_ZTS5State:
    .string "5State"
    .weak   _ZTI5State
    .section    .rodata._ZTI5State,"aG",@progbits,_ZTI5State,comdat
    .align 16
    .type   _ZTI5State, @object
    .size   _ZTI5State, 16
_ZTI5State:
    .quad   _ZTVN10__cxxabiv117__class_type_infoE+16
    .quad   _ZTS5State
    .section    .rodata
    .align 8
    .type   _ZZL18__gthread_active_pvE20__gthread_active_ptr, @object
    .size   _ZZL18__gthread_active_pvE20__gthread_active_ptr, 8
_ZZL18__gthread_active_pvE20__gthread_active_ptr:
    .quad   _ZL28__gthrw___pthread_key_createPjPFvPvE
    .weakref    _ZL28__gthrw___pthread_key_createPjPFvPvE,__pthread_key_create
    .ident  "GCC: (GNU) 4.8.0 20130502 (prerelease)"
    .section    .note.GNU-stack,"",@progbits

The function in question:

void
PlayState::LoadLevel(const std::string level_name)
{
    std::string full_path = level_directory + level_name;
    FileManager file(full_path, 'r');
    file.ReadLineString(' ');
    return;
}

The constructor for FileManager:

FileManager::FileManager(const std::string &path, char access_type)
{
    buffer = "";
    file.exceptions(std::fstream::failbit | std::fstream::badbit);
    try
    {
        switch (access_type)
        {
        case 'r':
            file.open(path, std::ios_base::openmode::_S_in);
            break;
        case 'w':
            file.open(path, std::ios_base::openmode::_S_out);
            break;
        default:
            std::cout << "Access type: " << access_type << " not recognised" << std::endl;
            break;
        }
    }
    catch(std::fstream::failure)
    {
        std::cout << "I/O exception in FileManager constructor.\nPlease check that the file exists.\nPath: " << path << "\nAccess type: " << access_type << std::endl;
    }
    return;
}

FileManager::ReadLineString:

/*
Reads the next line and returns it as a string
*/
std::string
FileManager::ReadLineString()
{
    getline(file, buffer);
    return buffer;

}

/*
As above, but allows to use of a delimiter.
*/
std::string
FileManager::ReadLineString(char delimiter)
{
    getline(file, buffer, delimiter);
    return buffer;
}

回答1:

I would take any such behavior by a debugger with a grain of salt. Try adding a print statement inside the constructor. Most likely, you’ll find that it’s not getting called twice at all. Debuggers easily get confused about what source line they’re on.

When in doubt, use assembly level stepping in the debugger (i.e. si / ni in gdb). That will remove any doubt what is truly executed.