I-7188ex's weird behaviour - c++98

I have quite complex I/O program (written by someone else) for controller ICPDAS i-7188ex and I am writing a library (.lib) for it that does some calculations based on data from that program.
Problem is, if I import function with only one line printf("123") and embed it inside I/O, program crashes at some point. Without imported function I/O works fine, same goes for imported function without I/O.
Maybe it is a memory issue but why should considerable memory be allocated for function which only outputs a string? Or I am completely wrong?
I am using Borland C++ 3.1. And yes, I can't use anything newer since controller takes only 80186 instruction set.

If your code is complex then sometimes your compiler can get stuck and compile it wrongly messing things up with unpredictable behavior. Happen to me many times when the code grows ... In such case usually swapping few lines of code (if you can without breaking functionality) or even adding few empty or rem lines inside code sometimes helps. Problem is to find the place where it do its thing. You can also divide your program into several files compile each separately to obj and then just link them to the final file ...
The error description remembers me of one I did fight with a long time. If you are using class/struct/template try this:
bds 2006 C hidden memory manager conflicts
may be it will help (did not test this for old turbo).
What do you mean by embed into I/O ? are you creating a sys driver file? If that is the case you need to make sure you are not messing with CPU registers. That could cause a lot of problems try to use
void some_function_or_whatever()
{
asm { pusha };
// here your code
printf("123");
asm { popa };
}
If you writing ISR handlers then you need to use interrupt keyword so compiler returns from it properly.
Without actual code and or MCVE is hard to point any specifics ...
If you can port this into BDS2006 or newer version (just for debug not really functional) then it will analyse your code more carefully and can detect a lot of hidden errors (was supprised when I ported from BCB series into BDS2006). Also there is CodeGuard option in the compiler which is ideal for finding such errors on runtime (but I fear you will not be able to run your lib without the I/O hw present in emulated DOS)

Related

Where accessing swap space is handled in Linux kernel?

I am working as research assistant and this question is really vital for our group:
We are looking for a way to inject delays when a process (i.e. a python program) is using swap space. For example, if in a normal way, it is swapping-in pages from swap space to main memory to work on it, we need to make a delay before that. (I know it doesn't make sense in real world to make delay in kernel when accessing swap space or main memory, but with doing that we will be able to simulate something which is important for us to do so.)
What I did before:
I already tried adding a printk statement to the following sections in the kernel but none of them seem to be the exact location of handling swap-in and swap-out for a process.
In the memory.c file, in the function do_swap_page(). It didn't work always.
In the memcontrol.c file, in the function mem_cgroup_swapin_charge_page. It just works when the application is newly allocating the swap space. (And not whenever it is using the swap actually)
In the swap_state.c file, in the function swapin_readahead() and also in the function swap_vma_readahead(). None of them works even when the process is using swap space.
Note 1: I am using the latest version of kernel (6.0.9). But I don't think it will be different with different versions of Linux kernel.
Note 2: I am measuring the amount of swap used with the command free -m. Also, more information is available in the /proc/meminfo file. So, I am sure that my process is using swap space, but I don't know how to catch it in the kernel sorce code.
It has been weeks that I a looking for an answer but no success. Any help is so appretiated. Thank you.

Why is Node.js's bytecode output so large?

Running node --print-bytecode on a file containing code as minimal as just void 0; produces a file the size of which is 2.3 MB. Looking through it, I thought it was including assembly code generated by JIT compilation, but that doesn't appear to be the case. Still, that doesn't explain why it's big. Compare it to the output of javap which, even though it's for a different language, is much smaller and much more readable.
I thought it was including assembly code generated by JIT compilation, but that doesn't appear to be the case.
Correct, bytecode is not assembly code. Assembly code will be generated later, for functions that run hot enough that V8 decides optimizing them is likely worth the time investment.
Why is Node.js's bytecode output so large? [...] on a file containing code as minimal as just void 0;
A lot of Node itself is written in JavaScript, and all of that gets compiled to bytecode before being executed. So even if you run Node on an empty file, you'll see quite a bit of bytecode.
What is it even saying though?
It's saying the same as the JavaScript code it was generated from. What exactly the individual bytecode instructions do and how to read them is an internal implementation detail of V8 and can change at any time. As a user of Node (or V8), you're not supposed to have a reason to care; and in particular you shouldn't assume that the bytecode format is stable over time/versions. Printing it at all is meant for debugging engine-internal issues.

how to replace a static kernel function without modifying and precomiling linux kernel

all,
I want to know how to replace a kernel static function in a module without modifying linux kernel.
I have known that Linux hook can replace some functions, but the
problem is that I want to replace a static function without modifying linux kernel.
Would you please help me ?
Thank you.
Generally the way the Linux kernel is compiled, replacing / hooking a static function at runtime isn't possible (short of unloading / reloading the entire module if you're talking module code).
That is because the compile inlines static functions much of the time (unless you take the address of it somewhere), and therefore they won't even show up in the symbol table. There's no way after the compile to find out where in the generated binary the static code ended up - not unlikely, you'll find several inlined versions of it in all the call sites invoking the func.
So the basic question: Why does the function have to be static ? What exactly is it you're attempting to do that mandates the use of static ?
If it's actually compiled as a module (not built-in), then just recompile the code, rmmod the module, and insmod the new .ko file. Easy as... some kind of cliche pastry.
In general, you may use some of this techniques:
kprobes/jprobes, that allows you to hook a function with int3
modifying the function's code (for ex., prologue) to jump to your handler and get back, later
If you don't wish to modify the kernel's code at all, you might set up the debugging registers and watch for an access exceptions (in your exception handler, of course). Besides that, you can try to find and invalidate some of the kernel's internal variables so the access to them from the kernel causes the invalid pointer dereference exception. In that case you can handle such an exception and do a back-trace to achive target function.

Controling CRT memory initialization

Occasionally you meet bugs that are reproducible only in release builds and/or only on some machines. A common (but by no means only) reason is uninitialized variables, that are subject to random behaviour. E.g, an uninitialized BOOL can be TRUE most of the time, on most machines, but randomly be initialized as FALSE.
What I wish I would have is a systematic way of flushing out such bugs by modifying the behaviour of the CRT memory initialization. I'm well aware of the MS debug CRT magic numbers - at the very least I'd like to have a trigger to turn 0xCDCDCDCD (the pattern that initializes freshly allocated memory) to zeros. I suspect one would be able to easily smoke out nasty
initialization pests this way, even in debug builds.
Am I missing an available CRT hook (API, registry key, whatever) that enables this? Anyone has other ideas to get there?
[Edit:] Seems clarifications are in order.
The usual magic numbers indeed have many advantages, but they do not provide coverage for bool initializations (always true), or bit fields that are tested against individual bit masks, or similar cases. Consistent zero initialization (that I'm able to toggle on and off, of course), would add a layer of testing that can surface bad init behaviour that can be rare otherwise.
I'm aware, of course, of CrtSetAllocHook. The hook thus set does not receive a pointer to the allocated buffer (it is called before such buffer was allocated), so it cannot overwrite it. Overloading global new wouldn't do much good either, as it would overwrite any valid constructor initialization.
[Edit:] #Michael, not sure what you mean by overriding new. Simple code like -
void* new(...)
{
void* res = ::new(...); // constructors now called!
if(SomeExternalConditionApplies())
OverWriteBufferWithMyPetValues(res);
}
would not work. Pasting and modifying the entire ::new code might work, but seems kinda scary (god only knows what I'd have to #include and link to get it to run).
I'm not following - having uninitialized memory set to something like 0xcdcdcdcd instead of 0 is better for flushing out bugs, because code is more likely get 'in range' arithmetic or specially handle 0. With the wildly invalid value, bugs are more likely to 'fail fast' so they can be fixed instead of hidden.
The values that the debug build of MSVC uses are specifically designed to help cause failures that can be easily detected:
they aren't 0, so NULL pointer checks against uninitialized memory won't hide the bug
they aren't valid pointers, so dereferencing uninitialized pointers will cause an access violation
they aren't 'usual' integer values, so calculations involving uninitialized data will usually result in wildly incorrect results that will tend to cause noticeable failures (I think be negative when handled as signed data also helps a bit with this, but not as much as simply being unusual numbers).
Also, they're easy to recognize in data displays in the debugger. Zero doesn't stand out nearly as much.
All that said, MSVC provides a number of debug hooks/APIs that you might be able to use to do something along the lines of what you want:
http://msdn.microsoft.com/en-us/library/1666sb98.aspx
Some additional information in response to your updated question:
You might be able to use a 3rd party debug allocation library like Dmalloc (http://dmalloc.com/) but I honestly don't know how easy those libraries are to integrate into an MSVC project, especially 'real world' ones.
Also, note that these obviously will only deal with dynamic allocations (and might not integrate well with MSVC's default new implementation).
You can use a global override of operator new() to deal with allocations that occur using new in C++ - there's not a problem with overwriting any valid constructor initializations - the new allocation occurs before the constructor performs any initialization (if you think about it for a moment it should be clear why that is).
Also, you might want to consider moving to Visual Studio 2010 - it will break into the debugger when you use an uninitialized local variable - doing nothing special other than running the Debug build under the debugger. Of course, MSCV has warned about many of these situations for a while, but VS2010 will catch the following in the debugger, which produces no warnings (at least with my current compiler settings):
int main( )
{
unsigned int x;
volatile bool a = false;
if (a) {
x = 0;
}
printf( "Hello world %u\n", x); // VS2010 will break here because x is uninitialized
return 0;
}
Even the Express version of VC++ 2010 supports this.
Just a suggestion: can you use the static code analysis tool in your compiler? /analyze will give you a C6001 warning that you're using uninitialized memory. And it's somewhat systematic, which is what your asking for.
Stepping into the CRT shows the magic numbers are used in _heap_alloc_dbg and realloc_help, and the value itself is encoded as
static unsigned char _bCleanLandFill = 0xCD; /* fill new objects with this */
Knowing what to search for often helps. The linked thread does have a nice suggestion: set a watch on _bCleanLandFill and modify it from the debugger.
It does work, but I'll keep this question open for a while - I still hope someone has a better idea... I was hoping to run automated tests with controlled initializations, and not have to do it manually (and only with a debugger available).

What functions does _WinMainCRTStartup perform?

This is part of a series of at least two closely related, but distinct questions. I hope I'm doing the right thing by asking them separately.
I'm trying to get my Visual C++ 2008 app to work without the C Runtime Library. It's a Win32 GUI app without MFC or other fancy stuff, just plain Windows API.
So I set Project Properties -> Configuration -> C/C++ -> Advanced -> Omit Default Library Names to Yes (compiler flag /Zl) and rebuilt.
Then the linker complains about an unresolved external _WinMainCRTStartup. Fair enough, I can tell the linker to use a different entry point, say MyStartup. From what I gather around the web, _WinMainCRTStartup does some initialization stuff, and I probably want MyStartup to do a subset of that.
So my question is: What functions does _WinMainCRTStartup perform, and which of these can I omit if I don't use the CRT?
If you are knowledgeable about this stuff, please have a look at my other question too. Thanks!
Aside: Why do I want to do this in the first place?
My app doesn't explicitly use any CRT functions.
I like lean and mean apps.
It'll teach me something new.
The CRT's entry point does the following (this list is not complete):
Initializes global state needed by the CRT. If this is not done, you cannot use any functions or state provided by the CRT.
Initializes some global state that is used by the compiler. Run-time checks such as the security cookie used by /GS definitely stands out here. You can call __security_init_cookie yourself, however. You may need to add other code for other run-time checks.
Calls constructors on C++ objects. If you are writing C++ code, you may need to emulate this.
Retrieves command line and start up information provided by the OS and passes it your main. By default, no parameters are passed to the entry point of the program by the OS - they are all provied by the CRT.
The CRT source code is available with Visual Studio and you can step through the CRT's entry point in a debugger and find out exactly what it is doing.
A true Win32 program written in C (not C++) doesn't need any initialization at all, so you can start your project with WinMainCRTStartup() instead of WinMain(HINSTANCE,...).
It's also possible but a bit harder to write console programs as true Win32 applications; the default name of entry point is _mainCRTStartup().
Disable all extra code generation features like stack probes, array checks etc. Debugging is still possible.
Initialization
Sometimes you need the first HINSTANCE parameter. For Win32 (except Win32s), it is fixed to (HINSTANCE)0x400000.
The nCmdShow parameter is always SW_SHOWDEFAULT.
If necessary, retrieve the command line with GetCommandLine().
Termination
When your program spawns threads, e.g. by calling GetOpenFileName(), returning from WinMainCRTStartup() with return keyword will hang your program — use ExitProcess() instead.
Caveats
You will run into considerable trouble when:
using stack frames (i.e. local variables) larger than 4 KBytes (per function)
using float-point arithmetic (e.g. float->int conversion)
using 64-bit integers on 32-bit machines (multiply, bit-shift operations)
using C++ new, delete, and static objects with non-zero-out-all-members constructors
using standard library functions like fopen(), printf() of course
Troubleshoot
There is a C standard library available on all Windows systems (since Windows 95), the MSVCRT.DLL.
To use it, import their entry points, e.g. using my msvcrt-light.lib (google for it). But there are still some caveats, especially when using compilers newer than MSVC6:
stack frames are still limited to 4 KBytes
_ftol_sse or _ftol2_sse must be routed to _ftol
_iob_func must be routed to _iob
Its initialization seems to run at load time. At least the file functions will run seemlessly.
Old question, but the answers are either incorrect or focus on one specific problem.
There are a number of C and C++ features that simply will not be available on Windows (or most operating systems, for that matter) if the programs actually started at main/WinMain.
Take this simple example:
class my_class
{
public:
my_class() { m_val = 5; }
int my_func(){ return m_val }
private:
int m_val;
}
my_class g_class;
int main(int argc, char **argv)
{
return g_class.my_func();
}
in order for this program to function as expected, the constructor for my_class must be called before main. If the program started exactly at main, it would require a compiler hack (note: GCC does this in some cases) to insert a function call at the very beginning of main. Instead, on most OSes and in most cases, a different function constructs g_class and then calls main (on Windows, this is either mainCRTStartup or WinMainCRTStartup; on most other OSes I'm used to it is a function called _start).
There's other things C++ and even C require to be done before or after main to work.
How are stdin and stdout (std::cin and std::cout) useable as soon as main starts?
How does atexit work?
The C standard requires the standard library have a POSIX-like signal API, which on Windows must be "installed" before main().
On most OSes, there is no system-provided heap; the C runtime implements its own heap (Microsoft's C runtime just wraps the Kernel32 Heap functions).
Even the arguments passed to main, argc and argv, must be gotten from the system somehow.
You might want to take a look at Matt Pietrick's (ancient) articles on implementing his own C runtime for specifics on how this works with Windows + MSVC (note: MinGW and Cygwin implement specific things differently, but actually fall back to MSVCRT for most things):
http://msdn.microsoft.com/en-us/library/bb985746.aspx

Resources