This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Add settings for expression evaluation memory allocations.
ClosedPublic

Authored by kuilpd on Apr 26 2023, 8:12 AM.

Details

Summary

Expression evaluation allocates memory for storing intermediate data during evaluation. For it to work properly it has to be allocated within target's available address space, for example within first 0xFFFF bytes for the 16-bit MSP430. The memory for such targets can be very tightly packed, but not all targets support GetMemoryRegionInfo API to pick an unused region, like MSP430 with MSPDebug GDB server.

These settings allow the programmer to manually pick precisely where and how much memory to allocate for expression evaluation in order not to overlap with existing data in process memory.

Diff Detail

Event Timeline

kuilpd created this revision.Apr 26 2023, 8:12 AM
kuilpd requested review of this revision.Apr 26 2023, 8:12 AM
jingham added inline comments.
lldb/source/Expression/LLVMUserExpression.cpp
340

This doesn't seem appropriate in generic code. You should ask the Arch plugin for this.

bulbazord requested changes to this revision.Apr 26 2023, 11:29 AM
bulbazord added inline comments.
lldb/source/Expression/LLVMUserExpression.cpp
340

Oh, I missed this in the previous patch. Yeah, we shouldn't be hardcoding llvm::Triple::msp430 in generic code. You're introducing even more uses of this in this patch, we should abstract this out into a plugin like Jim suggested.

This revision now requires changes to proceed.Apr 26 2023, 11:29 AM
kuilpd added inline comments.Apr 26 2023, 12:01 PM
lldb/source/Expression/LLVMUserExpression.cpp
340

Do you mean creating a new MSP430 plugin in lldb/source/Plugins/Architecture/, or accessing the existing ABI plugin? Should I create new methods for getting stack frame size in each existing plugin?

bulbazord added inline comments.Apr 27 2023, 9:51 AM
lldb/source/Expression/LLVMUserExpression.cpp
340

You could probably put this in the ABI plugin? The base ABI class could have a virtual method like GetStackFrameSize that returns 512 * 1024 and the MSP430 subclass can override it and return 512 instead. That should work, I think.

kuilpd updated this revision to Diff 518003.Apr 28 2023, 11:34 AM

Made an ABI method that returns a stack frame size for the target.

Removed the condition for alignment. The default value doesn't matter too much even for a 16-bit target, no need to add another ABI method just for this. The programmer can use the settings to change it if necessary.

asl added inline comments.Apr 28 2023, 11:53 AM
lldb/source/Expression/IRMemoryMap.cpp
180–181

is arch unused now?

kuilpd updated this revision to Diff 518010.Apr 28 2023, 11:59 AM
kuilpd marked 4 inline comments as done.

Removed unused variable arch.

bulbazord requested changes to this revision.Apr 28 2023, 1:21 PM

Mostly looks good to me, just a small thing about an implementation detail.

lldb/source/Expression/LLVMUserExpression.cpp
38

What in this file uses something from the lldb namespace now?

340–348

A few things:

  • I don't think you need to re-extract process from exe_ctx, the variable process at the beginning of this function should have a valid Process pointer in it already (see: LockAndCheckContext at the beginning of this function). We already assume target is valid and use it in the same way.
  • If we can't get an ABI from the Process, do we want to assume a stack frame size of 512 * 1024? Maybe there is a use case I'm missing, but if we don't have an ABI I'm not convinced that PrepareToExecuteJITExpression should succeed. LLDB will need some kind of ABI information to correctly set up the register context to call the JITed code anyway.
This revision now requires changes to proceed.Apr 28 2023, 1:21 PM
kuilpd added inline comments.Apr 28 2023, 2:37 PM
lldb/source/Expression/LLVMUserExpression.cpp
38

ABI class

340–348
  • I tried that, but a lot of tests fail on GetABI() after that, so had to re-extract it. Not sure why.
  • 512 * 1024 is what was hardcoded there by default. It makes sense that ABI has to exist, but leaving no default value in case if it's not retreived is weird as well. Or should we return an error in that case?
bulbazord added inline comments.Apr 28 2023, 2:58 PM
lldb/source/Expression/LLVMUserExpression.cpp
340–348

How do the tests fail? If the process is wrong that sounds like a pretty bad bug :(

I would think that we could return false with some logging or an error would be appropriate if we don't have an ABI. I may be misunderstanding something but I would think that the tests should still pass when we return false there... I hope.

kuilpd added inline comments.Apr 28 2023, 4:00 PM
lldb/source/Expression/LLVMUserExpression.cpp
340–348

Tried returning false, even more tests failed.
Did some digging, turns out expression can work without any target, right after starting LLDB.
So tests like this one fail because there is no target or process.

Sorry I should have brought this up earlier but I've noticed you don't have any tests with this change. Is it possible you could add something there? Something to make sure that these settings work as expected.

Sorry for the churn btw, I really appreciate your patience here.

lldb/source/Expression/LLVMUserExpression.cpp
340–348

Ah, right, I forgot! A given expression, if simple enough, might be compiled to LLVM IR and then interpreted instead of being compiled to machine code and run in the inferior... The fact that a stack frame size is even relevant in that case is strange but there's not much we can do about it without further refactors. Does something like this work then? If not, this should be fine.

if (stack_frame_size == 0) {
  ABISP abi_sp;
  if (process && (abi_sp = process->GetABI()))
    stack_frame_size = abi_sp->GetStackFrameSize();
  else
    stack_frame_size = 512 * 1024;
}

Sorry I should have brought this up earlier but I've noticed you don't have any tests with this change. Is it possible you could add something there? Something to make sure that these settings work as expected.

Should I do it also without a target?

Sorry for the churn btw, I really appreciate your patience here.

No worries, these are all valid points you raised :)

lldb/source/Expression/LLVMUserExpression.cpp
340–348

This worked, thanks!

Sorry I should have brought this up earlier but I've noticed you don't have any tests with this change. Is it possible you could add something there? Something to make sure that these settings work as expected.

Should I do it also without a target?

It's probably enough to just add a test with a target, the settings shouldn't mess with the non-target case I think.

kuilpd updated this revision to Diff 518520.May 1 2023, 12:11 PM

Rebased and added a test.

Instead of just getting a variable's address from allocated inside an expression, I decided to check for memory allocations inside logs. Exact variable address could change with the compilation changes, so this should be more reliable.

bulbazord accepted this revision.May 1 2023, 1:36 PM

Thanks for adding the test. The test itself doesn't seem portable and likely will fail on several platforms though I'm not sure which off the top of my head. After landing this, please watch the buildbots and be prepared to add the necessary decorators to the test to skip those platforms.

This revision is now accepted and ready to land.May 1 2023, 1:36 PM
kuilpd updated this revision to Diff 518801.May 2 2023, 11:00 AM

Rebased.

This revision was landed with ongoing or failed builds.May 2 2023, 11:03 AM
This revision was automatically updated to reflect the committed changes.