libera/#clasp - IRC Chatlog
Search
19:23:54
drmeister
Ok, so it's the register-save-area that causes the verification errors, not closure,nargs,farg0,farg1,farg2,farg3
19:24:20
Bike
the error was that there was no !dbg attachment, which would be true for either one, since they're both just generated with irc-intrinsic
19:24:23
drmeister
I'm saying I saw closure,nargs,farg0,farg1,farg2,farg3 for weeks without problems.
19:25:55
drmeister
I can't use closure,nargs,farg0,farg1,farg2,farg3 unless they are available throughout the function.
19:27:26
Bike
i think we have to figure out when we don't have source info at all, and then not use llvm.dbg.whatever at that point? maybe?
19:27:30
drmeister
Let's say we solve the !dbg attachment (I've fixed things like this in the past) how can we get the register save areas when we generate backtraces?
19:28:40
drmeister
It's going to be in call_with_frame - how would we get the register-save-areas for frames that provide it?
19:30:56
drmeister
I'd say we get the current frame pointer and then for each return address we lookup the size of its frame and then we subtract those sizes to break the stack up into frames.
19:31:16
drmeister
In a sane world without frame pointer elimination we would walk the linked list of frame pointers.
19:32:12
drmeister
If there is a facility to lookup the size of each frame - it will have to work with libraries and our jitted code. I know how to get DWARF info for out jitted code return addresses but libraries are a different matter.
19:34:30
drmeister
I'm also confused by libunwind. We can get RPB for each frame using a cursor - I see that. Can we get the start of each frame using a cursor?
19:37:18
drmeister
Presumably DWARF can still provide offsets of lexical variables when the frame pointer has been eliminated?
19:44:26
drmeister
So even if we have the DILocal info on a lexical variable using DWARF - we still have the problem of figuring out the start address of the stack frame.
19:49:40
drmeister
I get it. Unwinding the stack means figuring out where the return address after you unwind. If we knew this we would know everything we need.
19:59:14
Bike
lldb where do you initialize the frame base expression. how the hell can this not be obvious
20:08:37
drmeister
So it's looking like the eh_frame contains a table that maps IP to offsets to the return address on the stack - right?
20:09:01
drmeister
The eh_frame is in memory and it's relocated so that it works with absolute IP addresses.
20:09:45
Bike
okay, no, eh_frame does have it in a DWARF encoded way. the paper calls the frame address the "CFA" and that threw me off
20:10:35
drmeister
The authors of the paper describe compiling the bytecode to assembly code and speeding up unwinding 20x.
20:13:29
drmeister
Back to backtraces. Suppose we had a DWARF bytecode interpreter and we interpreted the eh_frame. We would take a return address and calculate the CFA for the frame to get the next return address.
20:15:52
drmeister
Maybe the CFA is the address of (or some constant offset from the address of) the next return address? Checking if libunwind gives us the address of the next return address...
20:26:23
Bike
i think libunwind does this. lldb definitely does, although i can't find the code where it gets the CFA expression to begin with
20:28:54
drmeister
Understood "CFA is the frame base, not the return address" - the return address will be at some offset from the CFA - right?
20:35:25
Bike
libunwind has a dwarf machine but it doesn't seem to be able to handle the fbreg instructions to get data from the frame
20:39:25
drmeister
Here is their DWARF compiler described in the paper: https://github.com/frdwarf/libunwind-eh_elf
20:40:14
Bike
that's interesting and all, but wouldn't we just be making things more complicated for ourselves?
20:40:51
drmeister
I'm not thinking about what to do moving forward yet. I'm just playing with ideas.
20:41:22
Bike
gnu libunwind does the cool thing where they use the preprocessor to construct function names, so it's hard to grep through
20:44:55
drmeister
What about this? https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib--unwind-backtrace.html
20:53:42
drmeister
The original problem was when we compile with clang and we link the gnu libunwind, JITted code that throws an exception fails.
20:55:36
drmeister
We throw an exception and a bunch of stuff happens where eh_frames are interpreted to generate tables that convert return addresses into the next return address to unwind the stack.
20:59:05
drmeister
I wonder if we had the udb debugger connected to clasp with and without libunwind linked in.
20:59:38
drmeister
We could look at the difference between what happens with libunwind and without libunwind when the exception is thrown from the JITted code.
21:02:07
drmeister
https://github.com/clasp-developers/clasp/blob/main/src/lisp/kernel/lsp/setf.lsp#L628
21:02:55
Colleen
Clhs: macro defmacro http://www.lispworks.com/documentation/HyperSpec/Body/m_defmac.htm
21:03:20
Bike
and it's a nonlocal return since early multiple-value-bind is macroexpanded into multiple-value-call of a lambda
21:05:09
drmeister
I wonder what is going on. It's essentially a try {.... inner(...) ... } catch (ReturnFrom& returnFrom) { ...} ... void inner(...){ throw ReturnFrom(...); }
21:08:49
Bike
trying to figure out what the personality is doing is probably more trouble than it's worth
21:09:49
drmeister
It's going to be running a virtual machine in here that is interpreting the bytecode in the eh_frame - and that virtual machine is not doing the right thing.
21:21:17
drmeister
We don't load compiled files anymore during aclasp build do we? I thought it was all interpreter all the time.
21:29:03
Bike
maybe just loading the compiler, compiling and loading setf.lsp, and then compiling a form with push in it?
21:34:24
drmeister
This is the first time that the link_intrinsics.cc throw is invoked - right - I can trap on that.
21:50:33
drmeister
And I have the non-libunwind version in another udb session and it compiled fine.
22:07:35
drmeister
Obvious difference is if I am in the _cxa_throw and put a break on __cxa_begin_catch
22:16:40
drmeister
The libunwind version starts in _Unwind_RaiseException but after the first instruction jumps to __libunwind_Unwind_RaiseException
2:08:44
drmeister
I'm trying llvm libunwind again. I realized that I had not configured llvm to use the patch properly
2:16:44
drmeister
He says that patch is what we need in the short term and he's talking to people at Apple about a long term fix.
3:14:49
drmeister
That patch was not correct for us because it only worked with the old memory manager - we are bleeding edge - using JITLink.
3:15:41
drmeister
Lang suggested I apply the same patch to this file: llvm/lib/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.cpp
3:21:08
drmeister
Think about how to use libunwind to get the frame pointers - then we can get rid of the frame pointer dereferencing code.
3:24:30
Bike
we can get it from RBP easily. if we have to worry about frame pointer omitting i don't think that's exposd by libunwind and we'd have to get into the dwarf