ทำให้ขั้นตอนภาษา. NET ของคุณถูกต้องในดีบักเกอร์


136

ประการแรกฉันต้องขออภัยสำหรับความยาวของคำถามนี้

ผมผู้เขียนของIronScheme เมื่อเร็ว ๆ นี้ฉันทำงานอย่างหนักในการส่งข้อมูลการดีบักที่เหมาะสมเพื่อที่ฉันจะสามารถใช้ดีบักเกอร์. NET 'เนทีฟ' ได้

แม้ว่าสิ่งนี้จะประสบความสำเร็จบางส่วน แต่ฉันก็ประสบปัญหาการงอกของฟัน

ปัญหาแรกเกี่ยวข้องกับการก้าว

เนื่องจาก Scheme เป็นภาษานิพจน์ทุกอย่างจึงมีแนวโน้มที่จะอยู่ในวงเล็บซึ่งแตกต่างจากภาษา. NET หลักซึ่งดูเหมือนจะเป็นคำสั่ง (หรือบรรทัด)

รหัสเดิม (Scheme) มีลักษณะดังนี้:

(define (baz x)
  (cond
    [(null? x) 
      x]
    [(pair? x) 
      (car x)]
    [else
      (assertion-violation #f "nooo" x)]))

ฉันมีจุดประสงค์ในการกำหนดแต่ละนิพจน์ในบรรทัดใหม่

โค้ดที่ปล่อยออกมาจะแปลงเป็น C # (ผ่าน ILSpy) มีลักษณะดังนี้:

public static object ::baz(object x)
{
  if (x == null)
  {
    return x;
  }
  if (x is Cons)
  {
    return Builtins.Car(x);
  }
  return #.ironscheme.exceptions::assertion-violation+(
     RuntimeHelpers.False, "nooo", Builtins.List(x));
}

อย่างที่คุณเห็นค่อนข้างเรียบง่าย

หมายเหตุ: หากรหัสถูกเปลี่ยนเป็นนิพจน์เงื่อนไข (? :) ใน C # สิ่งทั้งหมดจะเป็นเพียงขั้นตอนการดีบักหนึ่งขั้นตอนโปรดจำไว้ว่า

นี่คือเอาต์พุต IL พร้อมแหล่งที่มาและหมายเลขบรรทัด:

  .method public static object  '::baz'(object x) cil managed
  {
    // Code size       56 (0x38)
    .maxstack  6
    .line 15,15 : 1,2 ''
//000014: 
//000015: (define (baz x)
    IL_0000:  nop
    .line 17,17 : 6,15 ''
//000016:   (cond
//000017:     [(null? x) 
    IL_0001:  ldarg.0
    IL_0002:  brtrue     IL_0009

    .line 18,18 : 7,8 ''
//000018:       x]
    IL_0007:  ldarg.0
    IL_0008:  ret

    .line 19,19 : 6,15 ''
//000019:     [(pair? x) 
    .line 19,19 : 6,15 ''
    IL_0009:  ldarg.0
    IL_000a:  isinst [IronScheme]IronScheme.Runtime.Cons
    IL_000f:  ldnull
    IL_0010:  cgt.un
    IL_0012:  brfalse    IL_0020

    IL_0017:  ldarg.0
    .line 20,20 : 7,14 ''
//000020:       (car x)]
    IL_0018:  tail.
    IL_001a:  call object [IronScheme]IronScheme.Runtime.Builtins::Car(object)
    IL_001f:  ret

    IL_0020:  ldsfld object 
         [Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::False
    IL_0025:  ldstr      "nooo"
    IL_002a:  ldarg.0
    IL_002b:  call object [IronScheme]IronScheme.Runtime.Builtins::List(object)
    .line 22,22 : 7,40 ''
//000021:     [else
//000022:       (assertion-violation #f "nooo" x)]))
    IL_0030:  tail.
    IL_0032:  call object [ironscheme.boot]#::
       'ironscheme.exceptions::assertion-violation+'(object,object,object)
    IL_0037:  ret
  } // end of method 'eval-core(033)'::'::baz'

หมายเหตุ:เพื่อป้องกันไม่ให้ดีบักเกอร์เพียงแค่เน้นเมธอดทั้งหมดฉันจึงกำหนดจุดเข้าเมธอดให้กว้างเพียง 1 คอลัมน์

อย่างที่คุณเห็นนิพจน์แต่ละรายการจะจับคู่กับเส้นอย่างถูกต้อง

ตอนนี้ปัญหาเกี่ยวกับการก้าว (ทดสอบบน VS2010 แต่ปัญหาเดียวกัน / คล้ายกันใน VS2008):

สิ่งเหล่านี้IgnoreSymbolStoreSequencePointsไม่ได้ใช้

  1. เรียก baz ด้วย null arg มันทำงานได้อย่างถูกต้อง (null? x) ตามด้วย x
  2. โทรหา baz ด้วย Cons arg มันทำงานได้อย่างถูกต้อง (null? x) แล้ว (คู่? x) แล้ว (รถ x)
  3. โทรหา baz กับอาร์กิวเมนต์อื่นมันล้มเหลว (null? x) แล้ว (คู่? x) จากนั้น (รถ x) ตามด้วย (การยืนยัน - ละเมิด ... )

เมื่อสมัครIgnoreSymbolStoreSequencePoints(ตามคำแนะนำ):

  1. เรียก baz ด้วย null arg มันทำงานได้อย่างถูกต้อง (null? x) ตามด้วย x
  2. โทรหา baz ด้วย Cons arg มันล้มเหลว (null? x) แล้ว (คู่? x)
  3. โทรหา baz กับอาร์กิวเมนต์อื่นมันล้มเหลว (null? x) แล้ว (คู่? x) จากนั้น (รถ x) ตามด้วย (การยืนยัน - ละเมิด ... )

ฉันยังพบในโหมดนี้ว่ามีการไฮไลต์บางบรรทัด (ไม่แสดงที่นี่) อย่างไม่ถูกต้องซึ่งจะปิดด้วย 1

นี่คือแนวคิดบางประการที่อาจเป็นสาเหตุ:

  • Tailcalls ทำให้ดีบักเกอร์สับสน
  • ตำแหน่งที่ทับซ้อนกัน (ไม่แสดงที่นี่) ทำให้ดีบักเกอร์สับสน (ทำงานได้ดีมากเมื่อตั้งค่าเบรกพอยต์)
  • ????

ปัญหาที่สอง แต่ก็ร้ายแรงเช่นกันคือดีบักเกอร์ล้มเหลวในการทำลาย / ตีเบรกพอยต์ในบางกรณี

ที่เดียวที่ฉันจะทำให้ดีบักเกอร์แตกอย่างถูกต้อง (และสม่ำเสมอ) คือที่จุดเริ่มต้นของวิธีการ

สถานการณ์จะดีขึ้นเล็กน้อยเมื่อIgnoreSymbolStoreSequencePointsไม่ได้ใช้

สรุป

อาจเป็นไปได้ว่าดีบักเกอร์ VS เป็นเพียงบั๊กกี้ธรรมดา :(

อ้างอิง:

  1. การทำ CLR / .NET Language Debuggable

อัปเดต 1:

Mdbg ไม่ทำงานสำหรับแอสเซมบลี 64 บิต นั่นคือออก ฉันไม่มีเครื่อง 32 บิตให้ทดสอบอีกต่อไป Update:ฉันแน่ใจว่านี่ไม่ใช่ปัญหาใหญ่ใครมีวิธีแก้ไขหรือไม่? แก้ไข:ใช่ฉันโง่แค่เริ่ม mdbg ภายใต้พรอมต์คำสั่ง x64 :)

อัปเดต 2:

ฉันได้สร้างแอป C # และพยายามแยกข้อมูลบรรทัด

การค้นพบของฉัน:

  • หลังจากbrXXXคำสั่งใด ๆคุณต้องมีจุดลำดับ (หากไม่ถูกต้องหรือที่เรียกว่า '#line hidden' ให้ปล่อย a nop)
  • ก่อนbrXXXคำสั่งใด ๆให้ปล่อย '#line hidden' และ a nop.

อย่างไรก็ตามการใช้สิ่งนี้ไม่ได้ช่วยแก้ไขปัญหา (เพียงอย่างเดียว?)

แต่เพิ่มสิ่งต่อไปนี้ให้ผลลัพธ์ที่ต้องการ :)

  • หลังจากนั้นretปล่อย '#line hidden' และ a nop.

นี่คือการใช้โหมดที่IgnoreSymbolStoreSequencePointsไม่ได้ใช้ เมื่อนำไปใช้แล้วบางขั้นตอนจะยังคงข้าม :(

นี่คือเอาต์พุต IL เมื่อใช้ข้างต้น:

  .method public static object  '::baz'(object x) cil managed
  {
    // Code size       63 (0x3f)
    .maxstack  6
    .line 15,15 : 1,2 ''
    IL_0000:  nop
    .line 17,17 : 6,15 ''
    IL_0001:  ldarg.0
    .line 16707566,16707566 : 0,0 ''
    IL_0002:  nop
    IL_0003:  brtrue     IL_000c

    .line 16707566,16707566 : 0,0 ''
    IL_0008:  nop
    .line 18,18 : 7,8 ''
    IL_0009:  ldarg.0
    IL_000a:  ret

    .line 16707566,16707566 : 0,0 ''
    IL_000b:  nop
    .line 19,19 : 6,15 ''
    .line 19,19 : 6,15 ''
    IL_000c:  ldarg.0
    IL_000d:  isinst     [IronScheme]IronScheme.Runtime.Cons
    IL_0012:  ldnull
    IL_0013:  cgt.un
    .line 16707566,16707566 : 0,0 ''
    IL_0015:  nop
    IL_0016:  brfalse    IL_0026

    .line 16707566,16707566 : 0,0 ''
    IL_001b:  nop
    IL_001c:  ldarg.0
    .line 20,20 : 7,14 ''
    IL_001d:  tail.
    IL_001f:  call object [IronScheme]IronScheme.Runtime.Builtins::Car(object)
    IL_0024:  ret

    .line 16707566,16707566 : 0,0 ''
    IL_0025:  nop
    IL_0026:  ldsfld object 
      [Microsoft.Scripting]Microsoft.Scripting.RuntimeHelpers::False
    IL_002b:  ldstr      "nooo"
    IL_0030:  ldarg.0
    IL_0031:  call object [IronScheme]IronScheme.Runtime.Builtins::List(object)
    .line 22,22 : 7,40 ''
    IL_0036:  tail.
    IL_0038:  call object [ironscheme.boot]#::
      'ironscheme.exceptions::assertion-violation+'(object,object,object)
    IL_003d:  ret

    .line 16707566,16707566 : 0,0 ''
    IL_003e:  nop
  } // end of method 'eval-core(033)'::'::baz'

อัปเดต 3:

ปัญหาด้านบน 'กึ่งแก้ไข' Peverify รายงานข้อผิดพลาดในทุกวิธีเนื่องจากnopหลังจากretนั้น ฉันไม่เข้าใจปัญหาจริงๆ การnopตรวจสอบความผิดพลาดหลังจากไฟล์ret. มันเหมือนโค้ดที่ตายแล้ว (ยกเว้นว่ามันไม่ใช่โค้ด) ... อืมการทดลองดำเนินต่อ

อัปเดต 4:

กลับมาที่บ้านตอนนี้ลบรหัส 'ที่ไม่สามารถตรวจสอบได้' ซึ่งทำงานบน VS2008 และสิ่งต่างๆก็แย่ลงมาก บางทีการเรียกใช้โค้ดที่ไม่สามารถตรวจสอบได้เพื่อการดีบักที่เหมาะสมอาจเป็นคำตอบ ในโหมด 'ปล่อย' ผลลัพธ์ทั้งหมดจะยังคงตรวจสอบได้

อัปเดต 5:

ตอนนี้ฉันได้ตัดสินใจแล้วว่าแนวคิดข้างต้นของฉันเป็นทางเลือกเดียวที่ใช้ได้ในตอนนี้ แม้ว่ารหัสที่สร้างขึ้นจะไม่สามารถตรวจสอบได้ แต่ฉันก็ยังไม่พบอะไรVerificationExceptionเลย ฉันไม่รู้ว่าจะมีผลกระทบต่อผู้ใช้ปลายทางอย่างไรในสถานการณ์นี้

เพื่อเป็นโบนัสปัญหาที่สองของฉันได้รับการแก้ไขแล้ว :)

นี่คือscreencastเล็ก ๆ น้อย ๆของสิ่งที่ฉันลงเอยด้วย มันกระทบจุดพักไม่ก้าวที่เหมาะสม (เข้า / ออก / เหนือ) ฯลฯ สรุปแล้วเอฟเฟกต์ที่ต้องการ

อย่างไรก็ตามฉันยังไม่ยอมรับว่านี่เป็นวิธีที่จะทำ ฉันรู้สึกแฮ็คมากเกินไป มีคำยืนยันในประเด็นที่แท้จริงก็น่าจะดี

อัปเดต 6:

เพิ่งมีการเปลี่ยนแปลงเพื่อทดสอบโค้ดบน VS2010 ดูเหมือนว่าจะมีปัญหา:

  1. การโทรครั้งแรกไม่ถูกต้อง (การยืนยันการละเมิด ... ) ถูกตี กรณีอื่น ๆ ใช้ได้ดี รหัสเก่าบางตำแหน่งแสดงตำแหน่งที่ไม่จำเป็น ลบโค้ดแล้วใช้งานได้ตามที่คาดไว้ :)
  2. ที่สำคัญกว่านั้นคือเบรกพอยต์ล้มเหลวในการเรียกโปรแกรมครั้งที่สอง (โดยใช้การคอมไพล์ในหน่วยความจำการถ่ายโอนแอสเซมบลีไปยังไฟล์ดูเหมือนจะทำให้เบรกพอยต์มีความสุขอีกครั้ง)

ทั้งสองกรณีนี้ทำงานได้อย่างถูกต้องภายใต้ VS2008 ความแตกต่างที่สำคัญคือภายใต้ VS2010 แอปพลิเคชันทั้งหมดจะถูกคอมไพล์สำหรับ. NET 4 และภายใต้ VS2008 โดยคอมไพล์เป็น. NET 2 ทั้งที่รัน 64 บิต

อัปเดต 7:

ดังที่กล่าวไว้ฉันได้ mdbg ทำงานภายใต้ 64 บิต น่าเสียดายที่มันยังมีปัญหาเบรกพอยต์ที่ไม่สามารถพังได้หากฉันรันโปรแกรมอีกครั้ง (ซึ่งหมายความว่ามันได้รับการคอมไพล์ใหม่ดังนั้นจึงไม่ใช้แอสเซมบลีเดียวกัน แต่ยังคงใช้ซอร์สเดียวกัน)

อัปเดต 8:

ฉันได้ยื่นข้อบกพร่องที่ไซต์ MS Connect เกี่ยวกับปัญหาเบรกพอยต์

อัปเดต: แก้ไข

อัปเดต 9:

หลังจากคิดอยู่นานวิธีเดียวที่จะทำให้ดีบักเกอร์มีความสุขดูเหมือนว่าจะทำ SSA ดังนั้นทุกขั้นตอนสามารถแยกได้และเป็นลำดับ ฉันยังไม่ได้พิสูจน์ความคิดนี้ แต่ดูเหมือนว่ามีเหตุผล เห็นได้ชัดว่าการล้าง Temps จาก SSA จะทำให้การดีบักแตก แต่ง่ายต่อการสลับและการปล่อยทิ้งไว้ก็ไม่มีค่าใช้จ่ายมากนัก


ยินดีต้อนรับความคิดใด ๆ ฉันจะลองใช้และผนวกผลลัพธ์เข้ากับคำถาม 2 ไอเดียแรกลอง mdbg แล้วเขียนโค้ดเดียวกันใน C # แล้วเปรียบเทียบ
leppie

6
คำถามคืออะไร?
George Stocker

9
ฉันคิดว่าคำถามของเขาเป็นแนวว่า "ทำไมภาษาของฉันถึงก้าวไม่ถูกต้อง"
McKay

1
หากคุณไม่ผ่าน peverify คุณจะไม่สามารถทำงานในสถานการณ์ความน่าเชื่อถือบางส่วนเช่นจากไดรฟ์ที่แมปหรือในการตั้งค่าการโฮสต์ปลั๊กอินจำนวนมาก คุณสร้าง IL การสะท้อนกลับของคุณได้อย่างไรส่งผ่านข้อความ + อิลาสซึม ไม่ว่าในกรณีใดคุณสามารถใส่. line 16707566,16707566: 0,0 '' ด้วยตัวคุณเองได้ตลอดเวลาโดยที่คุณไม่ต้องกังวลว่าพวกเขาจะวาง nop หลังจากส่งคืน
Hippiehunter

@Hippiehunter: ขอบคุณ น่าเสียดายที่ไม่มีnops การก้าวล้มเหลว (ฉันจะตรวจสอบอีกครั้งเพื่อความแน่ใจ) มันเป็นการเสียสละที่ฉันคิดว่าฉันจะต้องทำ ไม่ใช่ว่า VS สามารถทำงานได้โดยไม่มีสิทธิ์ของผู้ดูแลระบบ :) Btw โดยใช้ Reflection ส่งผ่าน DLR (แฮ็กที่แตกแขนงต้น ๆ )
leppie

คำตอบ:


26

ฉันเป็นวิศวกรในทีม Visual Studio Debugger

แก้ไขฉันถ้าฉันผิด แต่ดูเหมือนว่าปัญหาเดียวที่เหลืออยู่คือเมื่อเปลี่ยนจาก PDB เป็นรูปแบบสัญลักษณ์คอมไพล์แบบไดนามิก. NET 4 จุดพักบางจุดจะพลาดไป

เราอาจจำเป็นต้องมีการทดสอบซ้ำเพื่อวินิจฉัยปัญหาอย่างแท้จริงอย่างไรก็ตามนี่คือบันทึกย่อบางส่วนที่อาจช่วยได้

  1. VS (2008+) สามารถรันในฐานะไม่ใช่ผู้ดูแลระบบ
  2. มีสัญลักษณ์ใด ๆ โหลดขึ้นเป็นครั้งที่สองหรือไม่? คุณอาจทดสอบโดยการเจาะ (ผ่านข้อยกเว้นหรือเรียก System.Diagnostic.Debugger.Break ())
  3. สมมติว่าสัญลักษณ์โหลดมีคำติชมที่คุณสามารถส่งถึงเราได้หรือไม่?
  4. ความแตกต่างที่เป็นไปได้คือรูปแบบสัญลักษณ์สำหรับโค้ดที่คอมไพล์แบบไดนามิกนั้นแตกต่างกัน 100% ระหว่าง. NET 2 (PDB stream) และ. NET 4 (IL DB ฉันคิดว่าพวกเขาเรียกมันว่า?)
  5. เสียงของ 'นพกำลังถูกต้อง ดูกฎสำหรับการสร้างจุดลำดับโดยนัยด้านล่าง
  6. คุณไม่จำเป็นต้องเปล่งสิ่งต่าง ๆ ในบรรทัด ตามค่าเริ่มต้น VS จะก้าวไปที่ 'คำสั่งสัญลักษณ์' โดยที่ในฐานะผู้เขียนคอมไพเลอร์คุณจะต้องกำหนดความหมายของ 'คำสั่งสัญลักษณ์' ดังนั้นหากคุณต้องการให้แต่ละนิพจน์เป็นสิ่งที่แยกจากกันในไฟล์สัญลักษณ์ก็จะใช้ได้ดี

JIT สร้างจุดลำดับโดยนัยตามกฎต่อไปนี้: 1. คำสั่ง IL nop 2. จุดว่างของ IL สแตก 3. คำสั่ง IL ทันทีตามคำสั่งเรียก

หากปรากฎว่าเราต้องการ repro เพื่อแก้ปัญหาของคุณคุณสามารถยื่นข้อบกพร่องในการเชื่อมต่อและอัปโหลดไฟล์อย่างปลอดภัยผ่านสื่อนั้น

อัปเดต:

เราขอแนะนำให้ผู้ใช้รายอื่นที่ประสบปัญหานี้ลองใช้ Developer Preview ของ Dev11 จากhttp://www.microsoft.com/download/th/details.aspx?displaylang=en&id=27543และแสดงความคิดเห็นพร้อมข้อเสนอแนะใด ๆ (ต้องเป้า 4.5)

อัปเดต 2:

Leppie ได้ตรวจสอบการแก้ไขแล้วว่าจะใช้งานได้กับ Dev11 เวอร์ชันเบต้าที่http://www.microsoft.com/visualstudio/11/en-us/downloadsตามที่ระบุไว้ในข้อผิดพลาดการเชื่อมต่อhttps://connect.microsoft com / VisualStudio / ข้อเสนอแนะ / รายละเอียด / 684089 / .

ขอบคุณ

ลุค


ขอบคุณมาก. ฉันจะลองทำซ้ำถ้าจำเป็น
leppie

สำหรับการยืนยันใช่คุณถูกต้อง แต่ฉันยังอยากจะแก้ปัญหาขั้นตอนโดยไม่ทำลายการตรวจสอบ VerificationExceptionแต่ในขณะที่กล่าวว่าฉันยินดีที่จะเสียสละว่าถ้าผมอาจจะพิสูจน์ได้ว่ามันจะไม่โยนรันไทม์
leppie

สำหรับประเด็นที่ 6 ฉันเพียงแค่ทำให้เป็น 'บรรทัด' สำหรับคำถามนี้ ในความเป็นจริงแล้วดีบักเกอร์ทำตามขั้นตอนอย่างถูกต้องใน / ออก / เหนือนิพจน์เช่นฉันตั้งใจให้มันทำงาน :) ปัญหาเดียวของวิธีการคือการตั้งค่าจุดพักบนนิพจน์ 'ภายใน' ถ้านิพจน์ 'ภายนอก' ครอบคลุมมัน ดีบักเกอร์ใน VS มีแนวโน้มที่จะต้องการให้นิพจน์ภายนอกมากที่สุดเป็นเบรกพอยต์
leppie

ฉันคิดว่าฉันได้แยกปัญหาเบรกพอยต์แล้ว ในขณะที่ทำงานภายใต้ CLR2 จุดพักจะถูกประเมินอีกครั้งเมื่อเรียกใช้โค้ดอีกครั้งแม้ว่าจะเป็นโค้ดใหม่ก็ตาม ใน CLR4 เบรกพอยต์จะ 'ยึดติด' กับโค้ดดั้งเดิมเท่านั้น ฉันได้ทำ screencast เล็ก ๆ ของพฤติกรรม CLR4 @ screencast.com/t/eiSilNzL5Nr สังเกตว่าชื่อประเภทจะเปลี่ยนไประหว่างการเรียกใช้
leppie

ฉันได้ยื่นข้อบกพร่องในการเชื่อมต่อ repro ค่อนข้างง่าย :) connect.microsoft.com/VisualStudio/feedback/details/684089
leppie

3

ฉันเป็นวิศวกรในทีม SharpDevelop Debugger :-)

แก้ปัญหาแล้วหรือยัง?

คุณพยายามแก้ไขข้อบกพร่องใน SharpDevelop หรือไม่? หากมีข้อบกพร่องใน. NET ฉันสงสัยว่าเราจำเป็นต้องใช้วิธีแก้ปัญหาบางอย่างหรือไม่ ฉันไม่ทราบถึงปัญหานี้

คุณพยายามแก้ไขข้อบกพร่องใน ILSpy หรือไม่? โดยเฉพาะอย่างยิ่งไม่มีสัญลักษณ์การดีบัก มันจะดีบักรหัส C # แต่มันจะบอกเราว่าคำแนะนำ IL นั้นดีบั๊กหรือไม่ (โปรดทราบว่าโปรแกรมดีบักเกอร์ ILSpy เป็นเบต้า)

บันทึกย่อเกี่ยวกับรหัส IL ดั้งเดิม:

  • .line 19,19: 6,15 '' เกิดขึ้นสองครั้ง?
  • .line 20,20: 7,14 '' ไม่เริ่มต้นในจุดลำดับโดยนัย (สแต็กไม่ว่างเปล่า) ผมกังวล
  • .line 20,20: 7,14 '' รวมรหัสสำหรับ "car x" (ดี) และ "#f nooo x" (ไม่ดี?)
  • เกี่ยวกับ nop หลังจาก ret. แล้ว stloc, ldloc, ret ล่ะ? ฉันคิดว่า C # ใช้เคล็ดลับนี้เพื่อสร้างจุดลำดับที่แตกต่างกัน

เดวิด


+1 ขอบคุณสำหรับข้อเสนอแนะในฐานะที่เป็นจุดแรกผลข้างเคียงที่ไม่ดีจากตัวสร้างโค้ด แต่ดูเหมือนจะไม่เป็นอันตราย ประเด็นที่สองนี่คือสิ่งที่ฉันต้องการ แต่ฉันเห็นจุดของคุณจะพิจารณา ไม่แน่ใจว่าจุดสุดท้ายหมายถึงอะไร
leppie

ประเด็นที่สามคือ. บรรทัด 22,22: 7,40 '' ควรอยู่ก่อน IL_0020 หรือควรมีบางอย่างก่อน IL_0020 มิฉะนั้นรหัสจะยังคงนับเป็น. บรรทัด 20,20: 7,14 '' จุดที่สี่คือ "ret, nop" อาจถูกแทนที่ด้วย "sloc, .line, ldloc, ret" ฉันเคยเห็นรูปแบบมาก่อนอาจจะซ้ำซ้อน แต่อาจมีเหตุผล
dsrbecky

ฉันไม่สามารถทำ stloc, ldloc ก่อนที่จะทำซ้ำเพราะฉันจะปล่อยหาง ฉันเข้าใจคุณหมายถึงเอาท์พุตดั้งเดิมหรือไม่?
leppie
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.