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

Incomplete CodeView debug information #1716

Open
14 of 23 tasks
rainers opened this issue Aug 21, 2016 · 16 comments
Open
14 of 23 tasks

Incomplete CodeView debug information #1716

rainers opened this issue Aug 21, 2016 · 16 comments

Comments

@rainers
Copy link
Contributor

rainers commented Aug 21, 2016

I've compiled my cv2pdb test file with LDC for Win64 and stepped through it in VS2015.
This is a list of problems I noticed:

  • void pointer: error shown
  • ubyte,byte: error shown
  • class/struct: no members shown
  • class/struct: static members not shown
  • UDT: unique name missing (clang writes it)
  • array: no type name
  • const void[] cvarr; const(char)[], const char[]: error shown (immutable ok)
  • lexical scope: variable life times set, "optimized away"
  • closure vars: show nonsense
  • class: base class not shown, base class members merged
  • assoc array: displays as unsigned char*
  • template class: arguments not in type name
  • ifloat/cfloat: error shown
  • x64: dynamic arrays implicitly passed by reference show wrong pointer
  • x64: static arrays passed as function argument not shown at all
  • x86: static arrays and structs passed to function by value show garbage
  • pointer to class reference passed to function displays garbage
  • vector types void16 and void32 shown as if they are delegates
  • arguments passed explicitely by "ref" not shown
  • typeof(null) causes "unspecified error"
  • vector types passed by value show bad values
  • function arguments not shown by call stack
  • no source language encoded into object file (LLVM 4.0 supports it, but writes MASM)

I've made this a list of checkable items as I'll try to work on these and track progress here.

Known gotchas, but probably ok:

  • arguments passed by reference are only shown if actually referenced in the callee, they might disappear after their lst usage.
@kinke
Copy link
Member

kinke commented Aug 21, 2016

Sounds like a very good plan. 👍
My understanding was that it's only a matter for LLVM to more or less fully support translating the currently emitted (incomplete) debug info to a .pdb, and that LDC itself wouldn't have to be adapted to use a different set of LLVM DebugInfo classes. So I'm keen on seeing how things will work out.

@rainers
Copy link
Contributor Author

rainers commented Aug 21, 2016

Yeah, the debug support inside LLVM looks like a DWARF to CodeView converter. It still needs some sensible input :)

@kinke
Copy link
Member

kinke commented Aug 31, 2016

Thanks, nice progress!

x64: struct value arguments implicitly passed by reference show wrong pointer

This one's new, right? And a major one. Does it show the source pointer, i.e., the argument before rewriting it via ExplicitByvalRewrite, which makes a bitcopy on the caller's stack and then passes a pointer to that copy as real parameter? IIRC, IrParam::value should be the correct pointer.

@rainers
Copy link
Contributor Author

rainers commented Aug 31, 2016

This one's new, right?

Yes. For main(string[] args) cdb shows struct string[] * args = 0x00000000 00000001. Not sure how this relates to the rewrite.

@kinke
Copy link
Member

kinke commented Aug 31, 2016

Ah. Delegates and slices currently aren't rewritten, we'd need to rewrite runtime function calls first. So in this case, the slice is passed as 2x64-bit aggregate, i.e., in the first 2 registers. So you see the array length instead of the pointer, which would be in the next register/dumped to memory right after the length field.

Edit: And struct string[] * should ideally become string *, right? Or is there even a way to specify a dynamic array length? That'd be really cool.

@kinke
Copy link
Member

kinke commented Aug 31, 2016

Oh I think the intent was to display it as a struct with both fields, i.e., as a struct string[] args (no pointer), with fields len and ptr.

@rainers
Copy link
Contributor Author

rainers commented Sep 1, 2016

Oh I think the intent was to display it as a struct with both fields, i.e., as a struct string[] args (no pointer), with fields length and ptr.

Yes, that would be expected, without bothering the user with the implementation details of the ABI. That's also what is displayed for x86.

BTW: my experiments with clang always show Variable optimized away for similar C++ code. Maybe there is some implementation missing in the LLVM part.

@rainers
Copy link
Contributor Author

rainers commented Sep 1, 2016

Just noticed that passing my own struct similar to a dynamic array works, delegates too. Passing a static array doesn't even declare the variable in the debug info (it's in the IR, though).

@kinke
Copy link
Member

kinke commented Oct 10, 2016

I'm impressed. A screenshot to let others know how far you got already :)

VS debugging

@rainers
Copy link
Contributor Author

rainers commented Oct 10, 2016

I'm impressed

Kudos to you, too :-)

@dnadlinger
Copy link
Member

Nice!

@TurkeyMan
Copy link

This is the most awesome thing I've seen today!

@kinke
Copy link
Member

kinke commented Jul 23, 2017

[Not CodeView-specific: I just used LLVM 4.0's DebugLoc::print() (don't know since when it's available) for our LL annotations, as it also includes filename/path. Although I used a relative src path ../current.d, no directory information whatsoever was printed, just current.d:line:column. So we may need to specify the full path to prevent issues in this regard.]

@rainers
Copy link
Contributor Author

rainers commented Jul 23, 2017

Yeah, the path should be absolute, and it already is, see ldc::DIBuilder::CreateFile

@kinke
Copy link
Member

kinke commented Aug 27, 2017

With #2292/#2294, a few (important) of the remaining bullet points should be done.

@void-995
Copy link
Contributor

void-995 commented Oct 5, 2018

PR for Associative Arrays: #2869

It differs a bit from what DMD is writing, but it has more consistent naming where debug type is shown as it was really named in front-end part.

LLMetadata *elems[] = {
      CreateNestedType(0, index, file, "__key_t"),
      CreateNestedType(0, value, file, "__value_t"),
      CreateMemberType(0, Type::tvoidptr, file, "impl", 0, Prot::public_)
};

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

No branches or pull requests

6 participants