Well, I am much happier now that I understand about dsymutil, and can actually step through my program in gdb. However, there are still some issues that are puzzling me.<div><br></div><div>1) First off, the debugger appears to stop at odd points. The IR for my main function looks correct to me:</div>
<div><br></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" face="'courier new', monospace">define i32 @"main(tart.core.Array[tart.core.String])->int"(%"tart.core.Array[tart.core.String]"* %args) {<br>
entry:<br> call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))<br> call void @llvm.dbg.stoppoint(i32 6, i32 22, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))<br>
%testModuleReflection = call { } @testModuleReflection() ; <{ }> [#uses=0]<br> call void @llvm.dbg.stoppoint(i32 7, i32 19, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))<br> %testModuleMethods = call { } @testModuleMethods() ; <{ }> [#uses=0]<br>
call void @llvm.dbg.stoppoint(i32 8, i32 16, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))<br> %testFindMethod = call { } @testFindMethod() ; <{ }> [#uses=0]<br> call void @llvm.dbg.stoppoint(i32 9, i32 10, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*))<br>
call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*))<br> ret i32 0<br>}</font></blockquote><div><div><br></div><div>However, when I single step into the function, it stops at the the *second* stop point. In fact, it appears to do this fairly consistently with all functions - the very first statement is always skipped.</div>
<div><br></div><div>Here's the original source (with line numbers) for reference:</div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" face="'courier new', monospace">1</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace">import tart.reflect.Module;<br>
2</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace">import tart.reflect.Method;<br>
3</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace"><br>
4</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace">@EntryPoint<br>
5</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace">def main(args:String[]) -> int {<br>
6</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace"> testModuleReflection();<br>
7</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace"> testModuleMethods();<br>
8</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace"> testFindMethod();<br>
9</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace"> return 0;<br>
10</font><span class="Apple-tab-span" style="white-space:pre"><font class="Apple-style-span" face="'courier new', monospace"> </font></span><font class="Apple-style-span" face="'courier new', monospace">}</font></blockquote>
<div><div><div><br></div><div>2) Another weird thing is that I can't seem to declare function variables that are not lvalues. The DIFactory::InsertDeclare method seems to require that the Storage parameter be the result of an alloca. However, what about function arguments that are passed by value, such as ints?</div>
<div><br></div><div>3) The same issue holds for immutable local variables. My language supports the concept of a "assign once" variable (like 'final' in Java). for which I use SSA values directly rather than storage created via alloca(). Does this means that there is no way to debug such variables?</div>
<div><br></div><div>4) There seems to be something weird going on with DW_TAG_inheritance: When I print out the type in the debugger I see <> symbols:</div><div><br></div></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;">
<font class="Apple-style-span" face="'courier new', monospace">2 = {<br> <> = {<br> <> = {<br> __tib = 0x0<br> }, <br> members of tart.reflect.Member: <br> _name = 0x0, <br> _fullName = 0x0, <br>
_kind = 0, <br><br> .. etc ...</font></blockquote><div><div><div><div><br></div></div><div><div>I'd like to see an example of DW_TAG_inheritance in the doc.</div><div><br></div><div>5) I can't seem to get the structure offsets to work. Here's what my generated IR for a struct member looks like (reformatted somewhat):</div>
<div><br></div></div></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><font class="Apple-style-span" face="'courier new', monospace">@llvm.dbg.derivedtype104 = internal constant %llvm.dbg.derivedtype.type {<br>
i32 458765,<br> { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),<br> i8* getelementptr inbounds ([10 x i8]* @.str103, i32 0, i32 0),<br> { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*),<br>
i32 27,<br> i64 mul (i64 ptrtoint (%1** getelementptr (%1** null, i32 1) to i64), i64 8),<br> i32 mul (i32 ptrtoint (%1** getelementptr (%38* null, i32 0, i32 1) to i32), i32 8),<br> i64 mul (i64 ptrtoint (%1** getelementptr (%tart.reflect.Member* null, i64 0, i32 2) to i64), i64 8),<br>
i32 0,<br> { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype102 to { }*) },<br> section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1]</font></blockquote><div><div><div><div><div>
<br></div><div>You can see the offset calculation on line 9. However, here's what dwarfdump reports for the entry:</div><div><br></div><div><div><font class="Apple-style-span" face="'courier new', monospace"> 0x00001dcd: member [10] </font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> name( "_fullName" )</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> type( {0x00001bbb} ( tart.core.String* ) )</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> decl file( "/Users/talin/Projects/tart/trunk/stdlib/tart/reflect/Module.tart" )</font></div><div><font class="Apple-style-span" face="'courier new', monospace"> decl line( 27 )</font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> data member location( +0 ) <-- huh?</font></div><div><br></div></div></div><div>6) It might be good to mention in the source-level debugging docs that line and column numbers are 1-based, not 0-based. I know that might seem obvious but it threw me off for a bit.</div>
</div></div><div><br></div><div>7) Another thing that confused me for a while is that the debugging APIs all want size, offset, and alignment values to be in bits, not bytes - but ConstantExpr::getSizeOf() et al return a size in bytes (which makse sense, since it behaves like C sizeof). More confusing, however, the comments for getSizeOf() doesn't say what units its result is in - I automatically assumed that getSizeOf and DIFactory were compatible. Probably the simplest thing would be to add a "getSizeOfInBits" method (and the same for align and offset) which could be used directly with DIFactory.</div>
<div><br></div><div>Note: All of the above results were produced with the current 2.6 branch head.</div></div><div><br>-- Talin<br>
</div>