Can someone give me any suggestions as to how to use this function from Lua:
HH_DISPLAY_TOPIC (MSDN)
I'm just a bit confused as to how to call the function as in is it from a dll or do I need to make a dll or is this a Luacom type of scenario.
Lua cannot go out into random DLLs and start calling random C functions1. If you want to call some code in a DLL, then you need to write a proper Lua module in C that will load this DLL and marshall the call from Lua to the DLL. Lua can read regular Lua modules and act accordingly.
1: If you're using LuaJIT, you can do this via their FFI stuff. To a degree, as you'll need to provide a string describing the interface for the functions you want to call.
Related
Lua's require(<name>) function, if called on a <name>.dll, will look for a function called luaopen_<name>.
What should I do if I want to say require("folder1.folder2.library")? It's not like I can name a function luaopen_folder1.folder2.library.
I am looking for a way to do this that doesn't involve changing Lua's module path—i.e. a way to do this that scales with the complexity of a project.
Name the function luaopen_folder1_folder2_library.
Is it possible to dynamically modify symbol table at runtime in C (in elf format on Linux)?
My eventual goal is the following:
Inside certain function say foo, I want to override malloc function to my custom handler my_malloc. But outside foo, any malloc should still call to malloc as in glibc.
Note: this is different from LD_PRELOAD which would override malloc during the entire program execution.
Is it possible to dynamically modify symbol table at runtime in C (in elf format on Linux)?
In theory this is possible, but in practice it's too hard to do.
Inside certain function say foo, I want to override malloc function to my custom handler my_malloc. But outside foo, any malloc should still call to malloc as in glibc.
Modifying symbol table (even if it were possible) would not get you to your desired goal.
All calls from anywhere inside your ELF binary (let's assume foo is in the main executable), resolve to the same PLT import slot malloc#plt. That slot is resolved to glibc malloc on the first call (from anywhere in your program, assuming you are not using LD_BIND_NOW=1 or similar). After that slot has been resolved, any further modification to the symbol table will have no effect.
You didn't say how much control over foo you have.
If you can recompile it, the problem becomes trivial:
#define malloc my_malloc
int foo() {
// same code as before
}
#undef malloc
If you are handed a precompiled foo.o, you are linking it with my_malloc.o, and you want to redirect all calls from inside foo.o from malloc to my_malloc, that's actually quite simple to do at the object level (i.e. before final link).
All you have to do is go through foo.o relocation records, and change the ones that say "put address of external malloc here" to "put address of external my_malloc here".
If foo.o contains additional functions besides foo, it's quite simple to limit the relocation rewrite to just the relocations inside foo.
Is it possible to dynamically modify symbol table at runtime in C (in elf format on Linux)?
Yes, it is not easy, but the functionality can be packaged into a library, so at the end of the day, it can be made practical.
Typemock Isolator++
(https://www.typemock.com/isolatorpp-product-page/isolate-pp/)
This is free-to-use, but closed source solution. The usage example from documentation should be instructive
TEST_F(IsolatorPPTests, IsExpired_YearIs2018_ReturnTrue) {
Product product;
// Prepare a future time construct
tm* fakeTime = new tm();
fakeTime->tm_year = 2018;
// Fake the localtime method
FAKE_GLOBAL(localtime);
// Replace the returned value when the method is called
// with the fake value.
WHEN_CALLED(localtime(_)).Return(fakeTime);
ASSERT_TRUE(product.IsExpired());
}
Other libraries of this kind
Mimick, from Q: Function mocking in C?
cpp-stub, from Q: Creating stub functionality in C++
Elfspy, for C++, but sometimes it's OK to test C code from C++ unittests, from Q: C++ mock framework capable of mocking non-virtual methods and C functions
HippoMocks, from Q: Mocking C functions in MSVC (Visual Studio)
the subprojects in https://github.com/coolxv/cpp-stub/tree/master/other
... there is still more, feel free to append ...
Alternate approaches
ld's --wrap option and linker scripts, https://gitlab.com/hedayat/powerfake
various approaches described in answers for Q: Advice on Mocking System Calls
and in answers to Q: How to mock library calls?
Rewrite code to make it testable
This is easier in other languages than C, but still doable even in C. Structure code into small functions without side-effects that can be unit-tested without resorting to trickery, and so on. I like this blog Modularity. Details. Pick One. about the tradeoffs this brings. Personally, I guturally dislike the "sea of small functions and tons of dependency injection" style of code, but I realize that that's the easiest to work with, all things considered.
Excursion to other languages
What you are asking for is trivial to do in Python, with the unittest.mock.patch, or possibly by just assigning the mock into the original function directly, and undoing that at the end of the test.
In Java, there is Mockito/PowerMock, which can be used to replace static methods for the duration of a test. Static methods in Java approximately correspond to regular functions in C.
In Go, there is Mockey, which works similarly to what needs to be done in C. It has similar limitations in that inlining can break this kind of runtime mocking. I am not sure if in C you can hit the issue that very short methods are unmockable because there is not enough space to inject the redirection code; I think more likely not, if all calls go through the Procedure Linkage Table.
I think I saw somewhere a native function in Lua that can return a new userdata. Does it exist? Is it possible to create custom userdata from normal Lua script?
You may be thinking of newproxy
From: http://lua-users.org/wiki/HiddenFeatures
newproxy is an unsupported and undocumented function in the Lua base
library. From Lua code, the setmetatable function may only be used
on objects of table type. The newproxy function circumvents that
limitation by creating a zero-size userdata and setting either a new,
empty metatable on it or using the metatable of another newproxy
instance. We are then free to modify the metatable from Lua. This is
the only way to create a proxy object from Lua which honors certain
metamethods, such as __len.
It was also useful for __gc metamethods, as a hack to get a callback when the newproxy instance becomes free.
This feature was present in Lua 5.1, but removed in 5.2. In Lua 5.2, __gc metamethods can be set on zero sized tables, so the main impetus for newproxy went away.
Actually no, in pure Lua.
The type userdata is provided to allow arbitrary C data to be stored in Lua variables. … Userdata values cannot be created or modified in Lua, only through the C API. This guarantees the integrity of data owned by the host program.
link
If you embed luaVM in host C/C++ application, you can export some function to create userdata to Lua, but it's not a good practice. UD is designed to be a blackbox for Lua scripts.
SWIG considers C's enum as userdata. (I checked the source it generated. Perhaps a bug?). Then, I need to create userdata inside the Lua scripts itself... Any good ways?
Then, I need to create userdata inside the Lua scripts itself.
No. You want to create one of the enumerator values within Lua. You do that pretty much as you would in C: use the enumerator's name. This is an object that has the value of the enumerator. However SWIG's Lua component decides to marshal this is irrelevant; just use the name in your Lua code.
I have a paramterised module in Erlang in which I wish to call a function A from within function B of the same parameterised module. How can I do this?
From this paper:
in every function of an abstract module, the variable THIS
is always implicitly bound to the current module instance
So you can simply write inside a function B:
THIS:A().
Just to recapitulate in an answer. You don't have to do anything special to call functions within a parametrised module, just write the code as you normally would. It is only when want to make an "remote" call to an exported function from within the module you need THIS:a(). Externally you need the parametrised module reference.
Though I agree with #Christian, stay away from them, you don't really need them.