I'm writing a DLL add-on for an application that internally has large parts written in assembly language. I'm mixing managed C++, unmanaged C++ and inline assembly.
I have just spent several hours debugging an issue that turns out to be that ebx is not preserved during a call into the main application. The bug only happens if the code runs in release mode and outside of the debugger. Release code in the debugger does not have this problem.
I have turned off all optimizations I can find for the Release Build, but it still depends on ebx. I have added push/pop ebx as a workaround, but this bug is sure to come up again. :-(
Is it possible to tell the compiler that ebx may be changed during a function call?
The error is in the prototype for the function which reports that it conforms to a calling convention without actually conforming to the calling convention's rules for register preservation. You need to wrap calls to the buggy function inside your own function that makes it conforming (by preserving registers), and have everybody call the wrapper. #pragma deprecated will let you enforce this policy.
Related
https://webassembly.studio/ allows inspection of WebAssembly (WASM) files and the corresponding SpiderMonkey-generated x86 code. I'd like to similarly inspect instructions generated by V8's WASM compilers (Liftoff and TurboFan).
I'm entirely unfamiliar with V8's codebase/API (I compiled & linked it and followed some tutorials, though). There seems to be a v8::CompiledWasmModule class available, but it does not seem to expose access to generated x86/x64 instructions by either Liftoff or TurboFan.
WebAssembly - adding a new opcode describes the process of adding a WASM opcode to V8. Seemingly appropriate functions for WASM compilation/execution are available in the mentioned classes. Though, these seem rather deeply layered within the V8 codebase and would be difficult to access were I to link V8 as a library. Also, I'm unsure if this corresponds to Liftoff or TurboFan.
Could anybody familiar with the V8 codebase give me some pointers as to how I can access Liftoff and/or TurboFan's WebAssembly compilation module, as to obtain x86/x64 code?
To inspect generated code, you can run the d8 shell with the --print-wasm-code flag. You'll need either a debug build, or a release build with the v8_enable_disassembler = true GN arg.
There's no existing way to retrieve generated code via V8's API; so if that's what you want, then you'd have to add it. Keep in mind that V8 is not designed to be a standalone compiler, which means generated code assumes that it's going to run "inside V8", so if you wanted to use it for anything else, you'd have to make significant modifications.
I'm posting this and then answering myself to document the issue for others.
I am using the TI CC2650 Launchpad with the Simplelink BLE stack. The project I compile and run is Project Zero (with edited code and additional profiles).
I want to place breakpoints in some functions inside the profile. For most of them i can't! When I look in the disassembly while debugging, I see that symbols are not available.
The only places I can place breakpoints are in main.c or inside callbacks.
How do I place breakpoints elsewhere? Where are my symbols?
So the deal was this - the functions I was trying to place breakpoints in were static functions, internal to the C modules containing them. Out of those, most were only used once in the code. So the compiler inlined them!
So in order to achieve debugging for these functions, one has to disable compiler optimizations. That disables inlining, and causes the symbols for those functions to generate.
I built a (customized) 1.8 HotSpot VM in Netbeans 7.2 using GDB 7.4 which works for executing Java programs. I want to debug a SIGSEGV that the program produces by calling a native function called by JNI that corrupts an object header.
However, I have some problems debugging the HotSpot VM: I have several breakpoints before the call to the main function in java.c. Sometimes, they trigger and sometimes the main function executes without all the breakpoints halting before. The most far I can get is
/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
After that, a step-in runs through the whole Java program, eventually triggering the SIGSEGV. The call is leading to the JNI API so I included the "hotspot/src/share/vm/prims" directory to the source dirs in the debug section. However, I could not see any effect. Does anybody have an idea how I can step into the C++ method calling the Java main method?
When the SIGSEGV causes the Netbeans debug view to stop, the call stack shows the expected call stack. However, instead of the C++ code it just shows assembler code while displaying the names of the C++ classes. The initial caller is "?? ()". Is there some way to see the C++ code or do I have to manually map the assembler code to the C++ code? I read a great article by Volker Simonis where he describes that such unknown frames relate to generated code. However, I'm still puzzled that the consecutive caller frames show class and method names. Is it a problem with source lookup or simply relates to the first unknown frame?
Did you compile hotspot in debug mode, i. e. make all_debug? If hotspot is optimised than code may be run in different order than it's in source file, and some symbols can be stripped out, preventing debugger to give you meaningful info, or setting a breakpoint.
With Irvine32.lib linked, and irvine32.inc included, I can invoke a few functions that VC originally does not support, such as Clrscr() or Gotoxy().
VC has never supported those functions.
So if I invoke Clrscr() somewhat, then the actual binary data for Clsscr() must be fired from some OS supported dlls such as ntdll.dll or kernel32.dll, both of which, however, clearly do not have it supported.
I Dumpbin-ed Irvine32.lib but I could not find the location from which that function is called.
How does Irvine32.lib magically make it available to call the unsupported functions I mentioned?
Thanks in advance.
The code for Irvine is available! If you looked at it you would see that Kip, used the following Win32 API calls to implement his versions:
Clrscr
GetConsoleScreenBufferInfo
WriteConsoleOutputCharacter
WriteConsoleOutputAttribute
SetConsoleCursorPosition
Gotoxy
SetConsoleCursorPosition
If you don't like his ways, you could always implement your own versions.
The canned DllMain for MFC 8.0 does not seem to call ExitInstance when it gets a DLL_PROCESS_DETACH. One possible solution is to define my own DllMain, but how do I tell the linker to use mine and not MFC's?
Or, is there another override which gets called on DLL_PROCESS_DETACH I'm not aware of?
I have had similar issues for a project compiled with /clr. Are you in the same situation? I was never able to trace it to a specific condition, but changing some static initializers to set null cleared it up. I think it has something to do with the order that static destructors are registered.
I'm not sure why your ExitInstance isn't called, but it's possible to define your own DllMain by copying the contents of MFC's dllmodul.cpp file into a file in your dll and adding any extra required functionality. The procedure is documented in this MS knowledge base article. Though it was written for MFC 4.0, I have used this method successfully for apps using MFC 8.0.