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

Fix: Parse DWARF5 Data16 values #12497

Merged
merged 1 commit into from
Sep 20, 2022

Conversation

stakach
Copy link
Contributor

@stakach stakach commented Sep 19, 2022

resolves crashes when raising errors on static MUSL crystal apps built on alpine:3.16

@straight-shoota straight-shoota added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:runtime labels Sep 19, 2022
@asterite
Copy link
Member

Wow, you did it! 🎉 How did you find it was this?

@straight-shoota
Copy link
Member

For reference: This was first reported in https://forum.crystal-lang.org/t/help-with-static-build/4936/9

@straight-shoota straight-shoota added this to the 1.6.0 milestone Sep 19, 2022
@straight-shoota
Copy link
Member

straight-shoota commented Sep 19, 2022

This is a follow-up to #11399 which originally implemented DWARF 5 support. Apparently I missed this case (probably because it was never used).

@asterite
Copy link
Member

Someone in Discord suggested this could go into 1.5.2. What do you think?

@luislavena
Copy link
Contributor

Someone in Discord suggested this could go into 1.5.2. What do you think?

That will be great! I was hitting the same issue today and before posting did some search, just to find the thread in the forum and this PR!

Thank you @stakach
❤️ ❤️ ❤️

@stakach
Copy link
Contributor Author

stakach commented Sep 19, 2022

Wow, you did it! 🎉 How did you find it was this?

Was monkey patching the code as you recommended, which required me to look at the implementation and work out where it was raising which led me to check the standard to find the enum value - then found @straight-shoota had already added the enum so I added the case

@stakach
Copy link
Contributor Author

stakach commented Sep 19, 2022

Would love to see this is 1.5.2 too

@stakach
Copy link
Contributor Author

stakach commented Sep 20, 2022

This monkey patch can be used as a workaround currently

{% if compare_versions(Crystal::VERSION, "1.5.2") < 0 %}
require "crystal/dwarf/info"

# debugging dwarf file issues
struct Crystal::DWARF::Info
  private def read_attribute_value(form, attr)
    case form
    when FORM::Addr
      case address_size
      when 4 then @io.read_bytes(UInt32)
      when 8 then @io.read_bytes(UInt64)
      else        raise "Invalid address size: #{address_size}"
      end
    when FORM::Block1
      len = @io.read_byte.not_nil!
      @io.read_fully(bytes = Bytes.new(len.to_i))
      bytes
    when FORM::Block2
      len = @io.read_bytes(UInt16)
      @io.read_fully(bytes = Bytes.new(len.to_i))
      bytes
    when FORM::Block4
      len = @io.read_bytes(UInt32)
      @io.read_fully(bytes = Bytes.new(len.to_i64))
      bytes
    when FORM::Block
      len = DWARF.read_unsigned_leb128(@io)
      @io.read_fully(bytes = Bytes.new(len))
      bytes
    when FORM::Data1
      @io.read_byte.not_nil!
    when FORM::Data2
      @io.read_bytes(UInt16)
    when FORM::Data4
      @io.read_bytes(UInt32)
    when FORM::Data8
      @io.read_bytes(UInt64)
    when FORM::Data16
      @io.read_bytes(UInt64)
      @io.read_bytes(UInt64)
    when FORM::Sdata
      DWARF.read_signed_leb128(@io)
    when FORM::Udata
      DWARF.read_unsigned_leb128(@io)
    when FORM::ImplicitConst
      attr.value
    when FORM::Exprloc
      len = DWARF.read_unsigned_leb128(@io)
      @io.read_fully(bytes = Bytes.new(len))
      bytes
    when FORM::Flag
      @io.read_byte == 1
    when FORM::FlagPresent
      true
    when FORM::SecOffset
      read_ulong
    when FORM::Ref1
      @ref_offset + @io.read_byte.not_nil!.to_u64
    when FORM::Ref2
      @ref_offset + @io.read_bytes(UInt16).to_u64
    when FORM::Ref4
      @ref_offset + @io.read_bytes(UInt32).to_u64
    when FORM::Ref8
      @ref_offset + @io.read_bytes(UInt64).to_u64
    when FORM::RefUdata
      @ref_offset + DWARF.read_unsigned_leb128(@io)
    when FORM::RefAddr
      read_ulong
    when FORM::RefSig8
      @io.read_bytes(UInt64)
    when FORM::String
      @io.gets('\0', chomp: true).to_s
    when FORM::Strp, FORM::LineStrp
      # HACK: A call to read_ulong is failing with an .ud2 / Illegal instruction: 4 error
      #       Calling with @[AlwaysInline] makes no difference.
      if @dwarf64
        @io.read_bytes(UInt64)
      else
        @io.read_bytes(UInt32)
      end
    when FORM::Indirect
      form = FORM.new(DWARF.read_unsigned_leb128(@io))
      read_attribute_value(form, attr)
    else
      raise "Unknown DW_FORM_#{form.to_s.underscore}"
    end
  end
end
{% end %}

@straight-shoota straight-shoota changed the title fix(crystal/dwarf/info): parse Data16 values Fix: Parse DWARF5 Data16 values Sep 20, 2022
@straight-shoota straight-shoota merged commit 292661e into crystal-lang:master Sep 20, 2022
@stakach stakach deleted the fix-dwarf-v5 branch September 20, 2022 21:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib:runtime
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants