Slice referring to out of scope data in zig language - zig

The get function below looks to me like it returns a slice referring to data in an array that will be out of scope once the function returns, and therefore is in error. Assuming this is true, is there any way to detect this at compile time or even run time in a debug mode?
I couldn't find any compiler flags that detected this error at compile time or run time and wondered if I'd missed anything that could help or this is just not something zig can detect at this time, which is fine, I'll just have to be more careful :)
This is a cut down example of a real issue I had which took some time to diagnose to demonstrate the problem
const std = #import("std");
fn get() []u8 {
var data : [100]u8 = undefined;
return data[0..99];
}
pub fn main() !void {
const data = get();
std.debug.print("Name: [{}]\n", .{data});
}

I believe that's behaviour that's not currently frowned upon by the compiler (0.6.0 at the time of writing), based on my understanding of the Lifetime and Ownership part of the docs:
It is the Zig programmer's responsibility to ensure that a pointer is
not accessed when the memory pointed to is no longer available. Note
that a slice is a form of pointer, in that it references other memory.
Although it might be addressed with this issue which describes similar behaviour: https://github.com/ziglang/zig/issues/5725

Related

Compiling lambda as Objective-C++ causes block cast

I have a non-copyable C++ lambda which captures a unique_ptr, and certain situations when compiling with Apple Clang as Objective-C++ cause the lambda to get converted to a block pointer, at which point the compilation fails due to an attempted copy of the lambda. A simple example is as follows:
int main(int argc, const char * argv[])
{
std::unique_ptr<int> myHeapInt = std::make_unique<int>(4);
int myStackInt = 0;
auto myLambda = [&, myHeapInt = std::move(myHeapInt)]()
{
myStackInt = *myHeapInt;
};
if(bool(myLambda)) //Error ar this point
{
*myHeapInt = 5;
}
std::invoke(myLambda);
return 0;
}
The error is as follows:
Call to implicitly-deleted copy constructor of 'const lambda...
Implicit capture of lambda object due to conversion to block pointer here
Is there a way around this conversion?
What is that bool(myLambda)? I have no clue.
The only thing you can do with a lambda is evoke it: myLambda(). You cannot test for whether it exists or anything.
So, I'm not entirely seeing the relevance of Objective-C++ here, as this code doesn't compile as C++ either:
objc++-noncopy-lambda.cpp:15:9: error: cannot convert '(lambda at objc++-noncopy-lambda.cpp:9:21)' to 'bool' without a conversion operator
if (bool(myLambda))
^~~~~~~~~~~~~
1 error generated.
The error message is different; I assume there's some attempt at implicitly converting lambdas to blocks in Objective-C++, I've tried to stay away from weird edge cases like that, but it seems that in the absence of an operator bool it might try the conversion to a block first.
Either way the code you're attempting to write doesn't make any sense and the compiler is correctly rejecting it.
I see in the comments that you're actually trying to do something different. Could you perhaps post a reduced version of the code you're actually trying to write, which supposedly compiles as C++ but not as Objective-C++?
I was trying to compile a templated header-file class replacement for std::function (github.com/Naios/function2) as Objective-C++, which implements a vtable and optimises it if the callable implements operator bool() or can be converted to bool.
In the end I just decided to disable this optimisation if compiled as Objective-C++ as converting to a block pointer is by design in Clang for block-lambda interoperability (http://clang.llvm.org/docs/LanguageExtensions.html#interoperability-with-c-11-lambdas).

Odd promiseKit 6 syntax behavior in Xcode

I am getting started with PromiseKit to prevent myself from writing functions with 10 levels of callbacks..
I installed the latest version (6.2.4) using CocoaPods, am running the latest version of xCode, imported PromiseKit in the file I am trying to get it working in, but I get really weird behavior of Xcode, resulting in several errors.
I intend to do something really basic to get started:
the function below creates filters (ProductListComponents) for categories for products in a product overview app I'm working on.
func createCategoryComponents(masterComponent: MasterComponent?) -> Promise<[ProductListComponents]> {
return Promise { seal in
//create a bunch of product category components
seal.resolve([components])
}
}
All fine here. I then try to get this:
firstly {
self.createCategoryComponents(masterComponent: masterComponent)
}.then { createdComponents in
completion.resolve(nil, createdComponents)
}
This refuses to work. firstly, when I try to type the firstly code, Xcode suggests:
firstly(execute: { () -> Guarantee<T> in
//code
})
and:
firstly(execute: { () -> Thenable in
//code
})
I have not seen this syntax in ANY of the PromiseKit documentation. It also suggests odd syntax for e.g. the .then calls. When accepting Xcode's suggestions, it obviously displays error as this is not the correct PromiseKit syntax. When ignoring Xcode's suggestion, I get this:
Obviously something is wrong here, my best guess is that something went wrong with the installation of PromiseKit. I have cleaned my project, re-installed the pod, restarted Xcode but it seems that nothing is working.
Question
Does anybody know what kind of issue I'm experiencing here and, even more importantly, how I might get it resolved?
Any helpt would be much appreciated.
According to the release notes:
then is fed the previous promise value and requires you return a promise.
done is fed the previous promise value and returns a Void promise (which is 80% of chain usage)
map is fed the previous promise value and requires you return a non-promise, ie. a value.
So, then shouldn't work here, because you need to return the promise value. If you just change then to the done it will work.
Also some suggestions.
firstly is really about visual decoration (i believe it was somewhere at PMK docs, but i can't find that right now), so, if this confuses you, try to remove that for the start;
The main feature of PMK is the chain. You definitely should write your code according to this principle;
Also, don't forget about errors. Use catch at the end of the chain for that.
Final example of your code:
firstly {
self.createCategoryComponents(masterComponent: masterComponent)
}
.done { createdComponents in
completion.resolve(nil, createdComponents)
}
.catch { error in
// don't forget about errors
}

Metal functions failing to compile with Xcode 8

Since moving to Xcode 8 and iOS10, my metal based app fails to run at all. On launch I get the error: "Compiler failed with XPC_ERROR_CONNECTION_INTERRUPTED"
This appears two to three times in the console before crashing due to a MTLComputePipelineState not being successfully created and throwing an error when calling the MTLDevice function makeComputePipelineState(function:). The only changes I have made to the project is to update to Swift 3.0, but the console seems to imply a compiler error, which due to the crash I'm assuming is down to some metal code not compiling properly.
Any help would be appreciated, this is ageing me prematurely.
UPDATE:
I've located the line causing the trouble in the .metal file:
int gi1 = permMod12[ii+i1+perm[jj+j1+perm[kk+k1]]];
permMod12 is a static constant array declared as:
static constant int permMod12 [512] = {7,4,5,7...}
perm is similarly static and constant:
static constant int perm [512] = {151,160...}
The variables ii, i1, jj, j1, kk and k1 are all integers calculated in the same kernel.
The kernel is quite large so I'll post a link to the GitHub location. It's the functions called simplex3D and simplex4D that are causing the issue. These are very similar so only focus on one of them, they are carbon copies but 4D has another stretch of variables running (ll, l1, l etc).
The issue certainly seems to be with looking up these arrays with calculated variables as when I change the variables to simple literals there is no error.
The kernel needs to be executed in order to get the error to occur.
Any help with this new info would be great.
I also encountered the same error: "Compiler failed with XPC_ERROR_CONNECTION_INTERRUPTED". The issue was resolved. It stemmed from attempted use of 'threadgroup bool' type variables. Refactoring the code to use 'threadgroup short' variables in place of the boolean resolved the error. (Could not find in the Metal Version 2 specification if bool type is or is not a valid threadgroup type.)
I've encountered this situation, and it seems that there is no unique solution to solve this problem. In my case, the problem was occurred when a texture that uses a normalized coordinate sampler also uses read() function. When I switch read() function to sample() this weird error was removed. I hope your problem were solved already.

Windriver VxWorks Simulator Self modifying code

Good morning.
I have a program that is Self-Modifying-Code.
Really, it build the binaries, which then are changed by ELFPatch and changes some function's prologues.
I am working with Windriver WorkBench 3.3 & VxWorks 6.9 Update3.
I created a standard simulator (PENTIUM),
when i run my code on the simulator:
void replace_prolog(void* func_ptr) {
char* p = (char*)func_ptr;
for (int i=0; i < PROLOGUE_SIZE; ++i)
p[i]=m_prologue[i]; // << prologue is a member array.
...
}
Let's call the Real Prologue : Original Prologue;
The Changed Prologue : Changed Prologue;
The One that is placed at Run-Time : Replacement Prologue;
I get an Exception (signal 11 - Segmentation Fault).
!! I realized it is VxWorks's .text Segment Protection.
So, I created a SimPC based VIP to be my simulator BSP, and excluded INCLUDE_PROTECT_TEXT (and all it's relevant kernel components)
and run the simulator:
Now, there is no exception!
Facts
Looking at Memory Browser I see the Changed Prologue Bytes (memory didn't change)!
Printing the buffer to console, prints the Replacement Prologue Bytes values! (Weird)
looking at assembly view (Mega Weird): shows the Changed Prologue Hex values but the Original Prologue asm commands (push bp;...) even though the byte value does not match them.
My Questions
Anyone had any experience with modifying .text segment?
Anyone encountered memory that would not change (without an exception/signal) on simulator, which is not a memory mapped port/volatile ?
Long Shot Assumption
I have an assumption it is about caching, hinting that vxWorks know this region shouldn't change, so it doesn't write_through, but don't know how i can check it...
EDIT 2: tried setting my pointers to be volatile => same behavior!
Please Help.
This may not be the answer but since you are seeing expected output, it confirms that .text section is changed. Only explanation I can think of is if you are using host tools to look at the .text memory then there is a possibility that information may be read from host.
Did you typed commands on target to look at the memory location?
Forgot about the question: but still have an answer.
there is an issue with the Host_Tools which does not show the changes to .text section.
while on the target, the bytes actually changed.
the function didn't work because my transformation was ruining dynamic linking.
my function code, had a call to function with a constant string "Whatever"
when i transformed the function code, i unintentionally, changed the reference of a relocation pointer which at loading time got a bad absolute PTR.
Lucky me, it pointed to a 0x00 buffer, and therefore printed an empty string without crashing.
Suggested Solutions:
Do not touch the relocated Pointers both when altering the Executable and altering at Run-time.
Create a static self-contained executable with absolute footprint => no dynamic relocation occurs that way.
alter dl() to transform the altered reloacted pointers back to their expected relocated.
alter dl() to infer from the altered relocated pointers the expected altered absolute pointer, so the transformation will create absolute pointer.
Note: I Choose #2 because it is the simplest, and because in my system, I do not need shared objects anyway.

Transitioning Audio Unit code to ARC

Apologies if this is too vague... this is my first post here and I'm well and truly stumped on this issue!
I've been attempting to transition an iOS Xcode project using Audio Units to ARC, but it appears to have broken the functionality of the audio unit processing class. Some symptoms... When I attempt referencing 'self' in AUProcessor.mm, the AUProcessor class is referred to as 'const*', whereas in the pre-ARC version, there was no 'const*' mentioned.
This pointer to 'self' produces the following error:
callbackStruct.inputProcRefCon = self;
[error] Assigning to 'void *' from incompatible type 'AUProcessor *const __strong'.
I can remove the error by adding (__bridge void*) ahead of self, which allows the project to compile. However, the Audio Unit processor doesn't work in the app.
I can't see anything elsewhere in the code that is significantly different from the pre-ARC version in terms of how the class is referenced.
Let me know if more context is required.
Thanks in advance!!
(BTW, thank you to all contributors to these forums... they are truly a wonderful resource for keen yet inexperienced programmers!)
Typically, (__bridge void*) would be the correct cast here. This means "take a pointer to this object without applying any memory management; I promise I'll hold onto it for as long as it's needed." (That last part is just implied, but if you don't, you'll crash.)
Are you certain that self continues to exist for as long as this audio unit? If nothing has a strong reference to self, then it will disappear and inputProcRefCon will become a dangling pointer.
When you say "doesn't work in the app," what do you mean? Does it crash? Does the callback not happen? When the callback happens, does it not have the right data?
I managed to resolve my issue by excluding the troublesome class from ARC using the compiler flag -fno-objc-arc.
Its not a very satisfying conclusion but at least my app is working again... Looks like I'm going to need to learn more about memory management!
The code below is working for me with the MusicPlayer API. I don't know that it is correct but I am not getting any errors or memory leaks. Hope it helps!
// assign the callback:
MusicSequenceSetUserCallback( sequence, MyEventCallback, (__bridge_retained void *)self );
//the callback method:
void MyEventCallback(void *inClientData,
MusicSequence inSequence,
MusicTrack inTrack,
MusicTimeStamp inEventTime,
const MusicEventUserData *inEventData,
MusicTimeStamp inStartSliceBeat,
MusicTimeStamp inEndSliceBeat)
{
struct MyMusicEventUserData* userEventData = ( MyMusicEventUserData *)inEventData;
[(__bridge MusicPlayerController*)inClientData MIDIEvent:userEventData
eventTime:inEventTime
startSliceBeat:inStartSliceBeat
endSliceBeat:inEndSliceBeat];
}

Resources