I am working on a project in which Lua (more specifically LuaJIT) is the scripting language but most of the heavy lifting is performed in C code. The C code is compiled into a .so file and LuaJIT's ffi capabilities are used to load the library and access the functions.
Let's say I set a breakpoint in the Lua code at the point where the C function is invoked. Can I "step into" the C code at that point and continue stepping through the C code as if I were using gdb?
No; ZeroBrane Studio debugger (it's using MobDebug) only supports stepping through Lua code. I don't think there is a debugger that integrates stepping through Lua and C code. You may be able to use two debuggers though: one for Lua and one for C code.
Related
What is the difference between compile time and run time?
I am learning the differnce between static languages and dynamic languages. I read thatin statically typed
languages the type checking is performed at "Compile time",whereas in case of dynamically typed languages
type checking is performed at "Run time".What exacly is compile time?Does the code gets compiled as we write
the code in an IDE?or it is compiled after we are done writing code.
I m speaking in context of modern ide like vscode where we have the code runner extension to write code.
I have learned basic python and C language.I have observed that in C we have to mention the datatype while
writing the code but not in python.
I trying to write some game, based on Love2d framework, compiled from moonscript. Every time when I make a mistake in my code, my application throws error and this error refers to compiled lua-code, but not a moonscript, so I have no idea where exactly this error happens. Tell me please, what a solution in this situation? Thanks.
Moonscript does support source-mapping/error-rewriting, but it is only supported when running in the moon interpreter: https://moonscript.org/reference/command_line.html#error_rewriting
I think it could be enabled in another lua environment but I am not completely sure what would be involved.
It would definetely require moonscript to hold on to the source-map tables that are created during compilation, so you couldn't use moonc; instead use the moonscript module to just-in-time compile require'd modules:
main.lua
-- attempt to require moonscript,
-- for development
pcall(require, 'moonscript')
-- load the main file
require 'init'
init.moon
love.draw = ->
print "test"
with this code and moonscript properly installed you can just run the project using love . as normal. The require 'moonscript' call will change require to compile moonscript modules on-the-fly. The performance penalty is negligible and after all modules have been loaded there is no difference.
Debugging is a problem for pretty much any source-to-source compilation system. The target language has no idea that the original language exists, so it can only talk about things in terms of the target language. The more divergent the target and original languages are, the more difficult debugging will be.
This is a big part of the reason why C++ compilers don't compile to C anymore.
The only real way to deal with this is to become intimately familiar with how the Moonscript compiler generates Lua from your Moonscript code. Learn Lua and carefully read the output Lua, comparing it to the given Moonscript. That will make it easier for you to map the given Lua error and source code to the actual Moonscript code that created it.
My main program is written by C. The C code calls an interpreter language, say python, by its C APIs. Then the interpreter language calls back to other C APIs. All the C code are debuggable, the interpreter language's C interface is also debuggable.
I found callgrind cannot profile the C code called by the interpreter language. Its call tree stops at the C code that calls the interpreter language.
Is this any known limitation of callgrind? Oracle Solaris Studio works at the case.
callgrind logic maintains the stack incrementally. This implies that it has to understand the calling convention of all what is on the stack, detect the
calls and the returns.
You might compare with the valgrind unwinder and the gdb unwinder using gdb+vgdb.
Start valgrind with: valgrind --vgdb-error=0 --vgdb=full ....
Put a breakpoint in the C code called by the interpreter language,
and continue the execution.
When breakpoint is encountered, compare the result of the 2 following
gdb commands:
backtrace
monitor v.info scheduler
The above will show if gdb and/or valgrind unwinders are working properly.
You can try to understand what callgrind does by using some valgrind
debugging options, e.g.
valgrind --tool=callgrind -v -v -v -d -d -d --ct-verbose=3
(adjust the nr of -v/-d/verbosity to your taste).
And of course, in case you have an old version of valgrind, you might
try with the last release or even the git repository, even if I doubt
something recently changed in this area.
I'm creating a script editor for my application, and I'd like to have it be able to run both C# and VB.NET scripts using Roslyn. I got this working with C# by using the CSharpScript class in the Microsoft.CodeAnalysis.CSharp.Scripting assembly/namespace, however there is no equivalent VisualBasicScript class that I can find, nor a Microsoft.CodeAnalysis.VisualBasic.Scripting assembly. I've scoured the web and can find nothing useful about running VB.NET scripts, and all the samples on the Roslyn github site are C#-specific. Am I missing something, or does support for running VB.NET scripts simply not exist the way it does for C# scripts?
Visual Basic Scripting is not currently available, presumably because it's not finished.
But its source is is the Roslyn repo, so you could try building it yourself.
When I do that, code like the following works for me:
Dim result = VisualBasicScript.RunAsync("Dim result = 1+1").Result
For Each variable In result.Variables
Console.WriteLine($"{variable.Name}: {variable.Value}")
Next
But this code does not work for me (it fails when compiling the script):
Console.WriteLine(VisualBasicScript.EvaluateAsync("1+1").Result)
I'm not sure whether this is because it's not finished, or whether it's intentional difference from C# scripting.
I've got working multiplatform Hello World code in Gas, NASM, and YASM, and I would like to shrink their corresponding executable files from 76KB to something more reasonable for a Hello World assembly program, seeing as a basic Hello World C program leads to an 80KB executable, and assembly should be much smaller. I believe the bulk of the executables are filled with junk from the linker options.
Trace:
LIBS=c:/strawberry/c/i686-w64-mingw32/lib/crt2.o -Lc:/strawberry/c/i686-w64-mingw32/lib -lmingw32 -lmingwex -lmsvcrt
ld ld -o $(EXECUTABLE) hello.o $(LIBS)
hello.exe
Hello World!
Code:
.data
msg: .ascii "Hello World!\0"
.text
.global _main
_main:
pushl $msg
call _puts
leave
movl $0, %eax
ret
If I remove any of the options in LIBS, either the link process fails, or the resulting executable raises a Windows error when it runs. So the logical thing to do is replace the puts call with something simpler, like sys_write, but I don't know how to do this multiplatform. The little documentation online says to use int 0x80 to perform a call to the kernel, but this only works in Linux, not in Windows, and I want my assembly code to be multiplatform.
Your program bloat comes mostly from the C runtime library. In Windows, a simple hello world program can be < 5K if you write your own "tiny" CRT. Here is a link to a project which explains all of the details about how to shrink your EXE to its smallest possible size:
http://www.codeproject.com/Articles/15156/Tiny-C-Runtime-Library
For Windows, you can call the native Win32 API functions, such as GetStdHandle() and WriteFile() to write directly to stdout.
For Unix-like systems, you can call the write() syscall with file descriptor 1 for stdout.
The details of exactly how you do each of these will depend on which assembler and OS you are using.
You should be able to link dynamically to the C runtime library instead of including it statically. I don't know how to do it in Linux, but in Windows you can use msvcrt.dll.
The assembler bloat is most likely coming from the C lib dependencies, especially for puts. refactoring the code to print Hello World without using a C call will most likely require OS-specific assembly code, as the Unix standard involves interrupts that make calls to the kernel, and Windows has its own VB-like API for such tasks.
I did manage to find a solution that would create small executable while still maintaining platform agnosticism. Ordinarily, C preprocessor directives would do the trick, but I'm not sure which assembly languages even have preprocessor syntax. But a similar effect can be achieved through the use of controlled, included assembly code files. A collection of wrapper code files can handle OS-specific assembly code, while an included assembly file does the rest. And a simple Makefile can run the respective build console commands to reference the respective wrapper code on the desired platform.
For example, I was able to quickly construct FASM code that works this way. (Though I have yet to inform it to actually bypass puts with something less bloaty.) Anyway, it's progress.
Because almost all C functions use the CDECL calling convention where you the caller adjusts the stack not the callee (the function).
You will get into trouble if you don't learn how to do things correctly now, read harder to trackdown bugs.
Try this:
push szLF
push esp
push fmtint2
call printf
add esp, 4 * 3
push msg
call puts
push szLF
push esp
push fmtint2
call printf
add esp, 4 * 3
Run it and notice the numbers before and after your call to puts. They are different no? Well, they are supposed to be the same. Now add:
add esp, 4
after your call to puts and run it again.. The numbers are the same now? That means you have a balanced stack pointer and the function uses the CDECL calling convention.