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

Parse debug information such as files and locations from .s files. #347

Closed
wants to merge 3 commits into from

Conversation

yurydelendik
Copy link
Contributor

LLVM backend can provide debug information about source code locations
for compiled bytecode in form of .file and .loc directives. We can store
and use them in s-expression format (via comments?), asm.js via source maps
and later in binary in additional sections.

@yurydelendik
Copy link
Contributor Author

yurydelendik commented Apr 14, 2016

Example of .s file (generated with clang -g1 option) (llvm needs https://gist.github.com/yurydelendik/a37b786dae40736ed7a1b04770f9c9ed):

        .text
        .file   "test.bc"
        .hidden test
        .globl  test
        .type   test,@function
test:
.Lfunc_begin0:
        .file   1 "test.c"
        .loc    1 1 0
        .param          i32
        .result         f32
        .local          f32
.Ltmp0:
        .loc    1 2 13 prologue_end
        f32.convert_s/i32       $1=, $0
.Ltmp1:
        .loc    1 4 12
        f32.const       $push0=, 0x1p1
        f32.div         $push1=, $pop0, $1
        .loc    1 4 3 is_stmt 0
        return          $pop1
.Ltmp2:
        .endfunc
.Lfunc_end0:
        .size   test, .Lfunc_end0-test

        .section        .debug_str,"MS",@progbits,1
.Linfo_string0:
    .....

s2wasm output:

(module
  (memory 1)
  (export "memory" memory)
  (export "test" $test)
  (;!file 1 "test.c";)
  (func $test (param $$0 i32) (result f32)
    (local $$1 f32)
    (;!loc 1 2 13;)
    (set_local $$1
      (f32.convert_s/i32
        (get_local $$0)
      )
    )
    (return
      (;!loc 1 4 12;)
      (f32.div
        (f32.const 2)
        (;!loc 1 4 12;)
        (get_local $$1)
      )
    )
  )
)

P.S. source

float test(int i) {
  float n = i;
  float c = 2.0f;
  return c / n;
}

@yurydelendik yurydelendik force-pushed the debug branch 5 times, most recently from e458bbd to 4ec135f Compare April 18, 2016 20:20
@kripken
Copy link
Member

kripken commented Apr 18, 2016

@sunfishcode: is the debug output from the backend stable? is now a good time to start parsing it as in this PR?

@kripken
Copy link
Member

kripken commented Apr 18, 2016

Also curious to hear @jfbastien and @dschuff's thoughts as well.

@jfbastien
Copy link
Member

It would be good to get @rossberg-chromium / @binji input on the representation of the debug info. I think the spec repo may be the best place to suggest a syntax first, instead of here.

@yurydelendik
Copy link
Contributor Author

yurydelendik commented Apr 18, 2016

Related conversation at WebAssembly/spec#258

Just to clarify. I want to limit this PR only to parsing of .s files (that we are producing with clang's '-g' flag). Embedding the debug info into wast or wasm format needs to be out of this PR scope (I placed this info as comments in wasm atm). So far we cannot only pull DWARF information about binding of virtual registers to the variable names, rest of it (files, line numbers, scopes) looks okay.

@sunfishcode
Copy link
Member

Yes, the debug output format follows DWARF, so while the details may change, the overall format is pretty stable.

That said, I expect any approach focused on translating a subset of DWARF into some other format will be a temporary solution.

@kripken
Copy link
Member

kripken commented Apr 19, 2016

Can you please elaborate as to why it would be temporary?

@sunfishcode
Copy link
Member

Because it will eventually be surpassed by browsers offering a debugging API, and content providing its own debuggers.

@yurydelendik
Copy link
Contributor Author

Just to make sure, the .s file produced by llvm webassembly backend will contain non-translated subset of DWARF stored in llvm assembly text format. The goal will be parse and repackage it into something browsers can consume (e.g. subsections in wasm, separate files, etc.). Is it correct?

@yurydelendik yurydelendik changed the title Storing debug information such as files and locations from .s files. Parse debug information such as files and locations from .s files. Apr 19, 2016
@yurydelendik
Copy link
Contributor Author

Changed title to better reflect the intent of the PR.

@binji
Copy link
Member

binji commented Apr 19, 2016

I don't really like that we're generating this debug information as comments in the wast format. I think it would be better to develop a design first so we can have it exist as a real node.

@yurydelendik yurydelendik force-pushed the debug branch 4 times, most recently from 89afc3e to 03e879e Compare April 25, 2016 19:00
@yurydelendik
Copy link
Contributor Author

Added '--debug-info' argument to the s2wasm to enable printing of the "debug" comments. More advanced example can be found at https://gist.github.com/yurydelendik/352dc3250d92191fc7f38dd0daf6a022 . Please notice that we might have "guide" bookmarks/labels in the text format to setup scope and ranges needed for debug sections:

(module
  (memory 1)
  (export "memory" memory)
  (export "test" $test)
  (;!file 1 "test.c";)
  (func $test (param $$0 i32) (result f32)
    (local $$1 f32)
    (;!bookmark test;)
    (;!bookmark .Ltmp0;)
    (;!loc 1 2 13;)
    (set_local $$1
      (f32.convert_s/i32
        (get_local $$0)
      )
    )
    (;!bookmark .Ltmp1;)
    (;!loc 1 4 3;)
    (return
      (;!loc 1 4 12;)
      (f32.div
        (;!bookmark test;)
        (f32.const 2)
        (;!bookmark .Ltmp1;)
        (;!loc 1 4 12;)
        (get_local $$1)
      )
    )
  )
.....
  (;!dbg_section .debug_loc,"",@progbits
.....
.Ldebug_loc2:
    .int32  .Ltmp1-.Lfunc_begin0
    .int32  .Lfunc_end0-.Lfunc_begin0
    .int16  7                       # Loc expr size
    .int8   16                      # DW_OP_constu
    .int8   128                     # 1073741824
    .int8   128                     # DW_OP_stack_value
    .int8   128                     # 
    .int8   128                     # 
    .int8   4                       # 
    .int8   159                     # 
    .int32  0
    .int32  0
    ;)
....

The example above shows that from '.Ltmp1' bookmark to '.Lfunc_end0' one, some variable ('c') can be evaluated using constant 2.0 (an expression can be more complex). The point is that we will need to mark AST node somehow to properly set ranges in the code, and single range in .s file might map into multiple "AST" ranges (? checking this atm).

LLVM backend can provide debug information about source code locations
for compiled bytecode in form of .file and .loc directives. We can store
and use them in s-expression format (via comments?), asm.js via source maps
and later in binary in additional sections.
@kripken
Copy link
Member

kripken commented Jan 23, 2017

Is this still relevant, or can we close it?

@kripken
Copy link
Member

kripken commented Feb 1, 2017

Closing due to inactivity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants