pthread_cancel behaves differently on arm and ppc? - embedded

I'm currently working on a multi-threaded application that would be deployed on arm and ppc architecture. I'm having some problem with pthread_cancel on arm.
pthread_cancel on arm doesn't behave the same with ppc. The thread gets cancelled but the destructor for the thread's local variable isn't being called on arm. I also tried explicitly defining a cancellation cleanup handler routine installed via pthread_cleanup_push. But it isn't being called when the thread is cancelled.
The code works fine with ppc. When a thread is cancelled, local variable's destructor is being called. And when I explicitly defined a cleanup handler, it was called and executed when pthread_cancel was called.
Am I missing something? Some compiler options perhaps?
Programming Language: C++
Compilers: arm-linux-g++/powerpc-linux-g++
OS: Linux
EDIT:
I have found a sort of similar problem logged on this libc bug.
Using gcc instead of g++ and adding -fno-exception compiler option did the trick. But I really want to understand stuff behind this issue. Moreover, the -fno-exception means I won't be able to perform exception handling in my application, not that I'm using it now but I might be in the future.
Thanks.

Thread cancellation without the help from the application is a bad idea. Just google. It is much better to tell the thread to end itself by setting a flag variable that is periodically checked by the thread.
Actually cancellation is so hard that it has been omitted from the latest C++0x draft. You can search http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html and won't find any mention of cancellation at all. Here's the definition of the proposed thread class (you won't find cancel there):
class thread
{
public:
// types:
class id;
typedef implementation-defined native_handle_type; // See [thread.native]
// construct/copy/destroy:
thread();
template <class F> explicit thread(F f);
template <class F, class ...Args> thread(F&& f, Args&&... args);
~thread();
thread(const thread&) = delete;
thread(thread&&);
thread& operator=(const thread&) = delete;
thread& operator=(thread&&);
// members:
void swap(thread&&);
bool joinable() const;
void join();
void detach();
id get_id() const;
native_handle_type native_handle(); // See [thread.native]
// static members:
static unsigned hardware_concurrency();
};

Related

How do clients and DLLs are compatible with respect to calling convnetion

Let's consider the following simple scenario:
// Library.dll
void Foo()
{
// some code
}
// main.c/cpp
int main()
{
// ...
Foo();
// ...
}
First:
From what i know, the caller and the callee must work with the same calling convention. And
if there is a full hand of calling conventions, how is it that we can just link
main.cpp with the Library.dll
and call Foo?
What guarantees that the caller and callee in this case uses the same calling convention?
Is this part of the problems that the COM architecture is trying to solve?
Second: I know there's a way to specify the type of calling convention
when declaring/defining a function. Is there a way to specify
a calling convention to the caller as well?
Clarifiaction
Maybe the question wasn't clear enough.
The question refers to a scenario in which the library was
compiled by some other developer, by an arbitrary compiler.
I compile my own main.cpp with my arbitrary compiler.
How can i be sure that both our compilers "Speak the same language"
with respect to calling conventions?

OBJC_PRINT_VTABLE_IMAGES and OBJC_PRINT_VTABLE_SETUP does not show any output

I've tried to use OBJC_PRINT_VTABLE_IMAGES and OBJC_PRINT_VTABLE_SETUP environmental variables on Objective-C executable in order to learn about vtable mechanism in Objective-C objects. Unfortunately the mentioned environment variables have no effect on console output, despite the fact that runtime acknowledged that the variables were set:
ยป OBJC_PRINT_OPTIONS=1 OBJC_PRINT_VTABLE_IMAGES=YES /Applications/TextEdit.app/Contents/MacOS/TextEdit
objc[41098]: OBJC_PRINT_OPTIONS is set
objc[41098]: OBJC_PRINT_VTABLE_IMAGES is set
I've tried to use both variables on executables provided by system (TextEdit) and my own. With no effect.
Whole vtable mechanism in Objective-C objects is obscure. It's hard to find information about this mechanism on Apple pages. There is some info from other sources, but no official documentation:
http://www.sealiesoftware.com/blog/archive/2011/06/17/objc_explain_objc_msgSend_vtable.html
http://cocoasamurai.blogspot.com/2010/01/understanding-objective-c-runtime.html
Why these variables are not working? Does vtables in current version of Objective-C are deprecated?
In this case, the answer is pretty straightforward - vtable dispatch is no longer optimized in the objective-c runtime, and was probably a bad idea in the first place.
vtable-based dispatch was one of the first attempts to speed up frequent calls in the objective-c runtime, but note that it predates the current method caching solution. The problem with using a fixed set of selectors as in the vtable solution not only means increased memory for every class in the runtime, but it also means that if you're using an architecture which doesn't result in isEqualToString: being called frequently, for example, you now have a completely wasted pointer for EVERY class in the runtime that overrides ONE of those selectors. Whoops.
Also, note that Vtable dispatch by design couldn't work on 32-bit architectures, which meant that once the iOS SDK was released, and 32bit was again a reasonable target for objective-c, that optimization simply couldn't work.
The relevant documentation that I can find for this is in objc-abi.h:
#if TARGET_OS_OSX && defined(__x86_64__)
// objc_msgSend_fixup() is used for vtable-dispatchable call sites.
OBJC_EXPORT void objc_msgSend_fixup(void)
__OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized")
__IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE;
Nowadays, there aren't many vestigial fragments of vtable dispatch left in the runtime. A quick grep over the codebase shows a few places in objc-runtime-new.mm:
#if SUPPORT_FIXUP
// Fix up old objc_msgSend_fixup call sites
for (EACH_HEADER) {
message_ref_t *refs = _getObjc2MessageRefs(hi, &count);
if (count == 0) continue;
if (PrintVtables) {
_objc_inform("VTABLES: repairing %zu unsupported vtable dispatch "
"call sites in %s", count, hi->fname());
}
for (i = 0; i < count; i++) {
fixupMessageRef(refs+i);
}
}
ts.log("IMAGE TIMES: fix up objc_msgSend_fixup");
#endif
And
*********************************************************************
* fixupMessageRef
* Repairs an old vtable dispatch call site.
* vtable dispatch itself is not supported.
**********************************************************************/
static void
fixupMessageRef(message_ref_t *msg)
Which pretty clearly indicates that it's not supported.
See also, the method stub for it (if you were to do it without a compiler generated call-site), found in objc-msg-x86_64.s:
ENTRY _objc_msgSend_fixup
int3
END_ENTRY _objc_msgSend_fixup
Where int3 is the SIGTRAP instruction, which would cause a crash if a debugger isn't attached (usually).
So, while vtable dispatch is an interesting note in the history of objective-c, it should be looked back as little more than an experiment when we weren't quite familiar with the best ways to optimize common method calls.

Same code won't work (kind of) in a shared library, but works when used directly in the program

I created a scripting language, when it worked perfectly, I put all the code in a shared library, and made a wrapper for it, but the same code won't work in the shared library. I've noticed that the code runs faster in the shared library, but it always crashes, due to memory problems, saying that the index is out of array length, but the very same code runs outside the library perfectly.
I've also noticed that if I reduce the amount of work it has to do, it lasts a bit longer before crashing.
My question here is that what is causing this crash, and how do I stop it from happening?
P.S: I haven't included all code, because the whole code is of 1039 lines (but if you need the code to solve the problem, then I could link to it), but I have tracked the crash to a function. And the confusing this is, that function always crashes on the 821st time it's called, never before, that's for a more optimized code, when the code was not optimized, and used more CPU, it would crash at 702.
Plus: I'm using DMD2, and the functions are exported using extern(C), And I'm testing all this on a Linux system, Ubuntu 14.04. And this is how I compile the library:
dmd -debug -gc "qscript.d" "qcompiler.d" "lists.d" "dllmain.d" "-shared" "-odobj/Debug" "-of/home/nafees/Desktop/Projects/QScr/QScr/bin/Debug/libQScr.so" -w -vcolumns
And is loaded using the dlopen function.
Again if you missed my question: what is causing this crash, and how do I stop it from happening? EDIT: and how can I disable the garbage collector, gc.disable doesn't work, gc is undefined.
EDIT: I have tracked 'why' the crash is occurring, I put up debug code all over the files, just to find out that the garbage collector is messing with the script file that was loaded in the memory. I 'fixed' the problem, not actually, by adding a check. It checks if the script is not 'alright', it reloads it into the memory. This is avoiding the crash, but the problem still exists. This changes the question to:
How can I disable the garbage collector> BTW, I tried gc.disable, but the DMD says that gc is undefined.
You must initialize the runtime when you load your shared library for the first time. To do so you need to add something like that to your library:
private __gshared bool _init = false;
import core.runtime: rt_init, rt_term;
export extern(C) void init()
{
if (!_init) rt_init;
}
export extern(C) void terminate()
{
if (_init) rt_term;
_init = false;
}
I really mean like that and not exactly that. Since we don't know how your scripting engine is used an init counter might also be valid:
private __gshared uint _init;
import core.runtime: rt_init, rt_term;
export extern(C) void init()
{
if (!_init) rt_init;
++init;
}
export extern(C) void terminate()
{
--init;
if (!_init) rt_term;
}
Anyway you should get the idea. The GC was undefined because you don't initialize the low level D runtime.
Solved the problem myself. AS I said in the Question's edit: I tracked the problem to the garbage collector, the garbage collector was messing with the script file that was loaded into the memory, that caused the library to crash, because the garbage collector had removed the script's contents from the memory. To solve this, I added:
import core.memory;
...
GC.disable();
This solved the whole problem.

What exactly does "Enable Strict Checking of objc_msgSend Calls" mean?

This is what I'm referring to:
From what I've read, an objc_msgSend is essentially what is happening at the c level when you send an Objective-C message, and this setting set to Yes ensures that the message being sent has the same number of arguments as the the receiver is expecting.
Is this correct? Also what are the advantages and disadvantages to setting this to Yes or No? Should I only set this to Yes in development and No in production?
You are essentially correct, yes.
Apple sets it to Yes by default because it helps to find errors faster. The only reason to set it to No would be because you are compiling legacy code that hasn't been updated to compile cleanly with this option on.
"Enable Strict Checking of objc_msgSend Calls" is a compile time check, not run time, so there is no benefit to turning it off in production.
There's a presentation "What's new in LLVM" on Apple's website (text of the presentation is here).
It looks like the compiler will now (optionally) strictly check the types of calls to obj_msgSend. You will have use a correctly-typed function pointer in place of directly calling objc_msgSend.
Example given:
#include <objc/message.h>
void foo(void *object) {
typedef void (*send_type)(void *, SEL, int);
send_type func = (send_type)objc_msgSend;
func(object, sel_getUid("foo:"), 5);
}

passing args in interrupt handler

consider we're writing a firmware for a baremetal MCU, i.e. no OS. I'm told it's not possible (illegal?) to pass arguments to interrupt handler function?
I can't precisely understand why it is so? What's wrong with this?
PS. is it possible to do in some RTOS-es, embedded Linux etc. or it si fundamentally wrong ?
Interrupts. do just that...interrupt. Imagine the doorbell at your home, interrupting you at any particular random time day or night. Can you be expected to at any moment have all the right items in your hand for any particular interrupt that can occur. You have to be able to cook dinner, take a shower, fold the laundry but just BEFORE the doorbell rings you must have exactly the correct items in both hands depending on the person ringing the bell, without any way of knowing they are there or are coming or are about to ring the bell. Not really possible. Same deal here, interrupts come at any particular time, for most processors immediately after the currently executing instruction, the interrupt handler is called, which means every single instruction would have to be trying to perform the foreground application while keeping all the parameters for the interrupt handler, and do all of this in one instructions time.
Now what is possible is with an operating system, or rtos or call it what you will, some layer. To have the real interrupt handler that knows nothing going in and has to figure it out, once it figures out what the interrupt is about to gather info and then call a high level interrupt handler that is passed parameters. Certainly possible and most/many operating systems do it this way.
No parameters can be explicitly passed to an interrupt handler because it is designed to be called by the hardware. Each architecture imposes a particular stack frame when it is called, typically including the saved state of the CPU.
If you also intend to call the interrupt handler from elsewhere in the code, you have either a design flaw, or there is some common code which could be factored out to be shared between the interrupt handler and the algorithmic code.
The only other thing I'll point out (that hasn't been mentioned so far) is the concept of a "software interrupt" (sometimes called a "trap"), which most processors support.
The idea is that a special instruction causes an exception to take place, and often with a software interrupt, either the opcode causing the exception, or registers set up prior to the exception, can contain values/arguments.
For example, in ARM processors, look up "SWI" or "SVC", depending on your architecture. I believe with the SWI instruction, the lower 8 bits are not part of the opcode - you can fill in whatever you want & pass a value from 0-255 (memory a little fuzzy here).
Unlike a hardware-initiated interrupt, which is totally asynchronous to the code running on the CPU, a software interrupt is synchronous - it occurs when the initiating instruction is executed (barring interrupt masking, nesting, etc.)
An interrupt handler is called by the hardware. It is "passed" whatever "arguments" the hardware passes it.
That's all there is.
when you setup an interrupt handler using the call below, it looks like the interrupt handler takes some args and returns irqreturn_t. Is this not the same interrupt handler OP is talking about?
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long flags,
const char *dev_name,
void *dev_id);
You can use shared variables set during normal code flow to affect the behaviour of an interrupt handler the next time it runs. But because you do not call the ISR directly, you cannot pass arguments. It is not a matter of legality, but rather technicality.
eg:
volatile enum
{
DO_NOTHING,
DO_A,
DO_B,
DO_C
} isr_action ;
__interrupt (SOME_IRQ) myISR()
{
switch isr_action
{
case DO_A :
{
// A
}
break ;
case DO_B :
{
// B
}
break ;
case DO_C :
{
// C
}
break ;
}
}
int main()
{
// Make ISR do A on next SOME_IRQ
isr_action = DO_A ;
for(;;)
{
// wait for interrupt
}
}