Variable sized arrays in Objective-C? - objective-c

Okay, so apparently this works:
void foo(size_t s) {
int myArray[s];
// ... use myArray...
}
Is this really legal? I mean, it must be, because it compiles (where the C compiler would reject it as non-constant). The first part of my question is: how does this work? I assume it's allocating it on the stack? Is this different from using alloca()?
Practically, I found some code that does this:
void bar(size_t chunkSize) {
CFReadStreamRef foo = NULL;
// ...some stuff to init foo...
while (stuffToDo) {
UInt8 buffer[chunkSize];
// ...read some data from stream into buffer
// using CFReadStreamRead()...
}
}
This works. However, when I move the buffer allocation from inside the loop to the first line of the function (directly before foo is declared), the function... stops working. In the debugger it gets to the first access of local variables and then just... exits. I don't see any exceptions being thrown, it doesn't crash, it just program carries on running (in reality the function returns a string and that return value is NULL, which is what the return variable is initialized to). I'm not sure what's going on. The second part of my questions is, in light of the first part, what the heck is going on?

it is legal in C99, although dangerous, and yes -- it is like alloca.
because it's like alloca, you want reasonably sized arrays when allocating on the stack. i am not sure if this is defined if the length is zero, but you could definitely cause a stack overflow if the array is 'large enough' to do so.
as far as what is going on -- pulling it out of the loop should make no difference if the sizes are reasonable. i suspect you are seeing undefined behavior because a parameter value is too large (or perhaps 0) -- you should validate the chunkSize parameter. the assembly will tell you why pulling it out of the loop makes a difference (assuming everything else in the program is well-formed).

Related

Hard Fault when dynamic memory allocaion in stm32f7

I am trying to implement a system so that it retrieves sound and extracts the mfcc of it. I'd like to implement my own mfcc function because librosa library wasn't implemented in C and other implementations of mfcc extractions doesn't yield the same outputs as librosa library does.
So I wrote a code, however, when I would like create hanning window, program doesn't take a step further and always stays the same statement while debugging. The statement is below:
float *mul = malloc(sizeof(float)*fftsize);
The whole code is as follows:
float* hanning(int fftsize){
float *mul = malloc(sizeof(float)*fftsize);
for (int i = 0; i<fftsize; i++){
mul[i] = 0.5 * (1 - cos(2*PI*i/(fftsize-1)));
}
return mul;
}
I put an LCD code to all error handler functions in stm32f7xx_it.c file to determine which fault I'm facing, and I see that it is hard_fault.
So what's the problem? I hope the issue is explained clearly. Due to the privacy, I couldn't put here whole code. Sorry for that. Thx in advance for your response.
Edit: I am chaning malloc to normal array with a variable length array. But still it takes me to HardFault_Handler function. SCB->SHCSR returns sometimes 65535 and sometimes 1.

What is the order of local variables on the stack?

I'm currently trying to do some tests with the buffer overflow vulnerability.
Here is the vulnerable code
void win()
{
printf("code flow successfully changed\n");
}
int main(int argc, char **argv)
{
volatile int (*fp)();
char buffer[64];
fp = 0;
gets(buffer);
if(fp) {
printf("calling function pointer, jumping to 0x%08x\n", fp);
fp();
}
}
The exploit is quite sample and very basic: all what I need here is to overflow the buffer and override the fp value to make it hold the address of win() function.
While trying to debug the program, I figured out that fb is placed below the buffer (i.e with a lower address in memory), and thus I am not able to modify its value.
I thought that once we declare a local variable x before y, x will be higher in memory (i.e at the bottom of the stack) so x can override y if it exceeds its boundaries which is not the case here.
I'm compiling the program with gcc gcc version 5.2.1, no special flags (only tested -O0)
Any clue?
The order of local variable on the stack is unspecified.
It may change between different compilers, different versions or different optimization options. It may even depend on the names of the variables or other seemingly unrelated things.
The order of local variables on the stack is not defined until compile/link (build) time. I'm no expert certainly, but I think you'd have to do some sort of a "hex dump", or perhaps run the code in a debugger environment to find out where it's allocated. And I'd also guess that this would be a relative address, not an absolute one.
And as #RalfFriedl has indicated in his answer, the location could change under any number of compiler options invoked for different platforms, etc.
But we do know it's possible to do buffer overflows. Although you do hear less about them now due to defensive measures such as address space layout randomization (ASLR), they're still around and paying the bills for someone I'd guess. There are of course many many online articles on the subject; here's one that seems fairly current(https://www.synopsys.com/blogs/software-security/detect-prevent-and-mitigate-buffer-overflow-attacks/).
Good luck (should you even say that to someone practicing buffer overflow attacks?). At any rate, I hope you learn some things, and use it for good :)

RenderScript Variable types and Element types, simple example

I clearly see the need to deepen my knowledge in RenderScript memory allocation and data types (I'm still confused about the sheer number of data types and finding the correct corresponding types on either side - allocations and elements. (or when to refer the forEach to input, to output or to both, etc.) Therefore I will read and re-read the documentation, which is really not bad - but it needs some time to get the necessary "intuition" how to use it correctly. But for now, please help me with this basic one (and I will return later with hopefully less stupid questions...). I need a very simple kernel that takes an ARGB Color Bitmap and returns an integer Array of gray-values. My attempt was the following:
#pragma version(1)
#pragma rs java_package_name(com.example.xxxx)
#pragma rs_fp_relaxed
uint __attribute__((kernel)) grauInt(uchar4 in) {
uint gr= (uint) (0.2125*in.r + 0.7154*in.g + 0.0721*in.b);
return gr;
}
and Java side:
int[] data1 = new int[width*height];
ScriptC_gray graysc;
graysc=new ScriptC_gray(rs);
Type.Builder TypeOut = new Type.Builder(rs, Element.U8(rs));
TypeOut.setX(width).setY(height);
Allocation outAlloc = Allocation.createTyped(rs, TypeOut.create());
Allocation inAlloc = Allocation.createFromBitmap(rs, bmpfoto1,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
graysc.forEach_grauInt(inAlloc, outAlloc);
outAlloc.copyTo(data1);
This crashed with the message cannot locate symbol "convert_uint". What's wrong with this conversion? Is the code otherwise correct?
UPDATE: isn't that ridiculous? I don't get this "easy one" run, even after 2 hours trying. I still struggle with the different Element- and variable-types. Let's recap: Input is a Bitmap. Output is an int[] Array. So, why doesnt it work when I use U8 in the Java-side Out-allocation, createFromBitmap in the Java-side In-allocation, uchar4 as kernel Input and uint as the kernel Output (RSRuntimeException: Type mismatch with U32) ?
There is no convert_uint() function. How about simple casting? Other than that, the code looks alright (assuming width and height have correct values).
UPDATE: I have just noticed that you allocate Element.I32 (i.e. signed integer type), but return uint from the kernel. These should match. And in any case, unless you need more than 8-bit precision, you should be able to fit your result in U8.
UPDATE: If you are changing the output type, make sure you change it in all places, e.g. if the kernel returns an uint, the allocation should use U32. If the kernel returns a char, the allocation should use I8. And so on...
You can't use a Uint[] directly because the input Bitmap is actually 2-dimensional. Can you create the output Allocation with a proper width/height and try that? You should still be able to extract the values into a Java array when you are finished.

Code only works if I NSLog some values - but why?

I'm writing a simple QR code generator (just for fun and to learn some Obj-C), and I'm working on tracing the outline of connected "modules" (i.e. the black squares that make up a QR code). This is in order to have nicer vector output than simply making a bunch of rects for each module.
Long story short, my outline-tracing code works - BUT ONLY if I make sure to call NSLog in a specific place! If I remove the NSLog-call, the code loops! I'm literally doing nothing but logging. And it doesn't matter what I log; I just have to call NSLog or things break.
The tracing algorithm is simple enough: Go clockwise around the shape of connected modules. When you hit a corner, turn right until you're back to following the outline of the shape. Stop when you reach the starting point again. The shape can have two modules that share a corner-point. The tracing-loop will thus hit that point twice. This is expected, and the code handles it correctly - if I call NSLog.
Otherwise, the code will say that a certain point is a corner the first time it sees it, and not a corner the second time, which causes the tracing to loop around. Detecting if something's a corner-point is not dependent on anything except the x and the y coordinates of the point and an array of module objects - but neither the modules nor the array changes while the tracing is going on, so given the same x,y you should always get the same result. And it does – if I call NSLog.
Without NSLog, the coordinates – e.g. (10,9) – is corner on moment, and a moment later (10,9) is suddenly not a identified as a corner. But with an NSLog-call, (10,9) is correctly seen as a corner-point every time.
Again: I change absolutely nothing; I just log something - anything! And suddenly it works. It's like it's saying that 2 == 2 is true or false, unless I tell it to log 2 and 2, in which case 2 == 2 is always true, as it should be.
Here's the flaky code. It's hard to understand out of context, but there's a lot of context, so I hope this is enough. Everything is integers (no fuzzy floating point values).
do { // start going around the shape
// If this isn't here or simply commented out, the code loops.
NSLog(#"foobar"); // doesn't matter what I log - I just need to log something
// Branch: Is current x,y a corner-point? This should
// always return the same result given the same X and Y
// values, but it only does if NSLog is there!
if( [self cornerAtX:x Y:y] ) {
// add the point to the path
[path addPoint:NSMakePoint(x, y)];
// rotate the direction clockwise, until
// the direction is following the edge of the
// the shape again.
do {
dt = dx;
dx = -dy;
dy = dt;
} while( ![self boundaryFromX:x Y:y inDirectionX:dx Y:dy] );
}
// continue along direction
x += dx;
y += dy;
} while( !(sx == x && sy == y) ); // we're back to the start of the shape, so stop
If anyone can tell me why NSLog can make code work (or rather: Why not using NSLog makes working code break), I'd be happy to hear it! I hope someone can make sense of it.
Make sure cornerAtX:Y: always returns something—i.e., that there's no code path that fails to return a value.
Otherwise, it may very well “return” whatever the last function you called returns, in which case calling NSLog (which doesn't return a value, but may ultimately call a function that does) causes it to “return” something different, which may always be something that's considered true.
The compiler should warn you if you fail to return a value from a function or method that you declared as doing so. You should listen to it. Turn on all the warnings you can get away with and fix all of them.
You should also turn on the static analyzer (also included in that post), as it, too, may tell you about this bug, and if it does, it will tell you step-by-step how it's happening.
There's not much to go on here, but I'd guess that it's either an uninitialized variable or some sort of memory stomping. NSLog probably uses both stack and heap memory, so it could affect those.
Have you tried replacing NSLog with some other meaningless operation? If that will also work then I suppose problem is linked to [self cornerAtX: x Y: y].
Another possibility is that the problem is time-related. NSLog takes time to execute, so if QR code is loaded in another thread you can see this kind of behavior.

Calling functions from within function(float *VeryBigArray,long SizeofArray) from within objC method fails with EXC_BAD_ACCESS

Ok I finally found the problem. It was inside the C function(CarbonTuner2) not the objC method. I was creating inside the function an array of the same size as the file size so if the filesize was big it created a really big array and my guess is that when I called another function from there, the local variables were put on the stack which created the EXC_BAD_ACCESS. What I did then is instead of using a variable to declare to size of the array I put the number directly. Then the code didnt even compile. it knew. The error wassomething like: Array size too big. I guess working 20+hours in a row isnt good XD But I am definitly gonna look into tools other than step by step debuggin to figure these ones out. Thanks for your help. Here is the code. If you divide gFileByteCount by 2 you dont get the error anymore:
// ConverterController.h
# import <Cocoa/Cocoa.h>
# import "Converter.h"
#interface ConverterController : NSObject {
UInt64 gFileByteCount ;
}
-(IBAction)ProcessFile:(id)sender;
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp);
#end
// ConverterController.m
# include "ConverterController.h"
#implementation ConverterController
-(IBAction)ProcessFile:(id)sender{
UInt32 packets = gTotalPacketCount;//alloc a buffer of memory to hold the data read from disk.
gFileByteCount=250000;
long LENGTH=(long)gFileByteCount;
CarbonTuner2(LENGTH,(long)8192/2, (long)4*2);
}
#end
void CarbonTuner2(long numSampsToProcess, long fftFrameSize, long osamp)
{
long numFrames = numSampsToProcess / fftFrameSize * osamp;
float g2DFFTworksp[numFrames+2][2 * fftFrameSize];
double hello=sin(2.345);
}
Your crash has nothing to do with incompatibilities between C and ObjC.
And as previous posters said, you don't need to include math.h.
Run your code under gdb, and see where the crash happens by using backtrace.
Are you sure you're not sending bad arguments to the math functions?
E.g. this causes BAD_ACCESS:
double t = cos(*(double *)NULL);
Objective C is built directly on C, and the C underpinnings can and do work.
For an example of using math.h and parts of standard library from within an Objective C module, see:
http://en.wikibooks.org/wiki/Objective-C_Programming/syntax
There are other examples around.
Some care is needed around passing the variables around; use the C variables for the C and standard library calls; don't mix the C data types and Objective C data types incautiously. You'll usually want a conversion here.
If that is not the case, then please consider posting the code involved, and the error(s) you are receiving.
And with all respect due to Mr Hellman's response, I've hit errors when I don't have the header files included; I prefer to include the headers. But then, I tend to dial the compiler diagnostics up a couple of notches, too.
For what it's worth, I don't include math.h in my Cocoa app but have no problem using math functions (in C).
For example, I use atan() and don't get compiler errors, or run time errors.
Can you try this without including math.h at all?
First, you should add your code to your question, rather than posting it as an answer, so people can see what you're asking about. Second, you've got all sorts of weird problems with your memory management here - gFileByteCount is used to size a bunch of buffers, but it's set to zero, and doesn't appear to get re-set anywhere.
err = AudioFileReadPackets (fileID,
false, &bytesReturned, NULL,0,
&packets,(Byte *)rawAudio);
So, at this point, you pass a zero-sized buffer to AudioFileReadPackets, which prompty overruns the heap, corrupting the value of who knows what other variables...
fRawAudio =
malloc(gFileByteCount/(BITS/8)*sizeof(fRawAudio));
Here's another, minor error - you want sizeof(*fRawAudio) here, since you're trying to allocate an array of floats, not an array of float pointers. Fortunately, those entities are the same size, so it doesn't matter.
You should probably start with some example code that you know works (SpeakHere?), and modify it. I suspect there are other similar problems in the code yoou posted, but I don't have time to find them right now. At least get the rawAudio buffer appropriately-sized and use the values returned from AudioFileReadPackets appropriately.