I'm working with a structure IMAGE_T (shown below, excuse the French) with its own alloc function.
typedef struct {
int nbl; /* nombre de ligne de l'image */
int nbc; /* nombre de colonnes de l’image */
unsigned char **data; /* tableau bidim des pixels de l’image */
} IMAGE_T;
IMAGE_T *alloc_image(int nbl, int nbc){
int taille = nbl*nbc+100;
IMAGE_T * image;
image = (IMAGE_T *) calloc(taille, sizeof(unsigned char));
return image;
}
When going through the debugger, it bugs out stating:
"unhandled exception at: 0xc0000005: access violation reading location 0x00000000."
..which I'm pretty sure relates to alloc_image not functioning properly. Any suggestions?
(And for further info, after declaring an IMAGE_T I'm then use another function that returns IMAGE_T *, which itself contains the function alloc_image within it, in order to allocate the memory. Is there anything wrong with this?)
Thanks
I suspect the reason you're getting an access violation is because you're trying to work with the "data" member which calloc() would have made null when allocating the memory.
That said, I'd like to understand why the "data" member in IMAGE_T is a unsigned char **? Why not simply a unsigned char *? (And then, alloc_image must allocate memory to IMAGE_T and then, within that allocated structure, allocate space for the "data".)
Related
I have a trivial program:
int main(void)
{
const char sname[]="xxx";
sem_t *pSemaphor;
if ((pSemaphor = sem_open(sname, O_CREAT, 0644, 0)) == SEM_FAILED) {
perror("semaphore initilization");
exit(1);
}
sem_unlink(sname);
sem_close(pSemaphor);
}
When I run it under valgrind, I get the following error:
==12702== Syscall param write(buf) points to uninitialised byte(s)
==12702== at 0x4E457A0: __write_nocancel (syscall-template.S:81)
==12702== by 0x4E446FC: sem_open (sem_open.c:245)
==12702== by 0x4007D0: main (test.cpp:15)
==12702== Address 0xfff00023c is on thread 1's stack
==12702== in frame #1, created by sem_open (sem_open.c:139)
The code was extracted from a bigger project where it ran successfully for years, but now it is causing segmentation fault.
The valgrind error from my example is the same as seen in the bigger project, but there it causes a crash, which my small example doesn't.
I see this with glibc 2.27-5 on Debian. In my case I only open the semaphores right at the start of a long-running program and it seems harmless so far - just annoying.
Looking at the code for sem_open.c which is available at:
https://code.woboq.org/userspace/glibc/nptl/sem_open.c.html
It seems that valgrind is complaining about the line (270 as I look now):
if (TEMP_FAILURE_RETRY (__libc_write (fd, &sem.initsem, sizeof (sem_t)))
== sizeof (sem_t)
However sem.initsem is properly initialised earlier in a fairly baroque manner, firstly by explicitly setting fields in the sem.newsem (part of the union), and then once that is done by a call to memset (L226-228):
/* Initialize the remaining bytes as well. */
memset ((char *) &sem.initsem + sizeof (struct new_sem), '\0',
sizeof (sem_t) - sizeof (struct new_sem));
I think that this particular shenanigans is all quite optimal, but we need to make sure that all of the fields of new_sem have actually been initialised... we find the definition in https://code.woboq.org/userspace/glibc/sysdeps/nptl/internaltypes.h.html and it is this wonderful creation:
struct new_sem
{
#if __HAVE_64B_ATOMICS
/* The data field holds both value (in the least-significant 32 bytes) and
nwaiters. */
# if __BYTE_ORDER == __LITTLE_ENDIAN
# define SEM_VALUE_OFFSET 0
# elif __BYTE_ORDER == __BIG_ENDIAN
# define SEM_VALUE_OFFSET 1
# else
# error Unsupported byte order.
# endif
# define SEM_NWAITERS_SHIFT 32
# define SEM_VALUE_MASK (~(unsigned int)0)
uint64_t data;
int private;
int pad;
#else
# define SEM_VALUE_SHIFT 1
# define SEM_NWAITERS_MASK ((unsigned int)1)
unsigned int value;
int private;
int pad;
unsigned int nwaiters;
#endif
};
So if we __HAVE_64B_ATOMICS then the structure has a data field which contains both the value and the nwaiters, otherwise these are separate fields.
In the initialisation of sem.newsem we can see that these are initialised correctly, as follows:
#if __HAVE_64B_ATOMICS
sem.newsem.data = value;
#else
sem.newsem.value = value << SEM_VALUE_SHIFT;
sem.newsem.nwaiters = 0;
#endif
/* pad is used as a mutex on pre-v9 sparc and ignored otherwise. */
sem.newsem.pad = 0;
/* This always is a shared semaphore. */
sem.newsem.private = FUTEX_SHARED;
I'm doing all of this on a 64-bit system, so I think that valgrind is complaining about the initialisation of the 64-bit sem.newsem.data with a 32-bit value since from:
value = va_arg (ap, unsigned int);
We can see that value is defined simply as an unsigned int which will usually still be 32 bits even on a 64-bit system (see What should be the sizeof(int) on a 64-bit machine?), but that should just be an implicit cast to 64-bits when it is assigned.
So I think this is not a bug - just valgrind getting confused.
I seem to have a problem deleting a char* array. It crashes due to heap corruption as delete[] gets called:
typedef struct _CDB_SYMBOL_INFO {
char * name;
unsigned long address;
unsigned long value;
} CDB_SYMBOL_INFO;
// ...
for each( Symbol ^ symbol in bls->Symbols )
{
CDB_SYMBOL_INFO symbol_info;
symbol_info.name = new char[symbol->Name->Length];
Marshal::Copy( symbol->Name->ToCharArray(), 0, IntPtr( (char*) symbol_info.name ), symbol->Name->Length );
// see enumerate_cdb_symbols_callback(..)
cdb_call_back(&symbol_info, *call_back);
delete[] symbol_info.name; // Crashes here
}
// ...
I don't see the problem here ..
static int enumerate_cdb_symbols_callback(CDB_SYMBOL_INFO * info, void * call_back)
{
EnumerateSymbolsCallBack *cb = (EnumerateSymbolsCallBack*)call_back;
Symbol * symbol = alloc_symbol();
cb(0, symbol);
return 0;
}
You're calling the Marshal::Copy overload for an array of 16-bit elements (.NET System::Char is not C++ char!), and the fourth parameter is the number of elements not the number of bytes, so you're actually copying symbol->Name->Length * 2 bytes, which is twice the size of your buffer. The resulting overflow corrupts heap metadata, causing delete[] to crash.
Either use a buffer of type wchar_t, which is the C++ type that matches System::Char, or convert the string to ASCII, perhaps by replacing ToCharArray() with Encoding::ASCII::GetBytes(symbol->Name). Or UTF-8, in which case you can't assume that symbol->Name->Length is the necessary buffer size.
An even simpler way is to use the marshal_as library that comes with C++/CLI:
#include <msclr\marshal_cppstd.h>
using namespace msclr::interop;
for each( Symbol ^ symbol in bls->Symbols )
{
std::string sym_name = marshal_as<std::string>(symbol->Name);
CDB_SYMBOL_INFO symbol_info;
symbol_info.name = &sym_name[0];
// see enumerate_cdb_symbols_callback(..)
cdb_call_back(&symbol_info, *call_back);
}
It does some unspecified single-byte character encoding (most likely ASCII), and uses RAII to free the memory automatically.
Today I'm writing this program and I had has two problems.
This is the full code in Objective-C for a OS X Project:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
int numx;
int quadr;
NSLog(#"Inserisci un numero");
scanf("%i", &numx);
quadr = numx * numx;
NSLog(#"Il quadrato del tuo numero %i è: ", numx, quadr);
}
return 0;
}
The second NSLog reports this error: Data argument not used by format string. Why it create this kind of error? In which way I can solve this error?
More over the run-time of the program finish unexpectly after that the output has written: "Inserisci un numero". When I insert the number requiry, the program not display the number squared as required from the second NSLog. Why I'm having this interrupt? Help me please. I what to understand what is happenend.
The warning you get on that line is correct.
The quadr parameter you pass is not used in the format string. Each parameter you pass need to have a % equivalent in the format string.
Specify the extra parameter in your code sample conform line below:
NSLog(#"Il quadrato del tuo numero %i è %i", numx, quadr);
Given I have a type specifier as returned by method_copyReturnType(). In the GNU runtime delivered with the GCC there are various methods to work with such a type specifier like objc_sizeof_type(), objc_alignof_type() and others.
When using the Apple runtime there are no such methods.
How can I interpret a type specifier string (e.g. get the size of a type) using the Apple runtime without implementing an if/else or case switch for myself?
[update]
I am not able to use the Apple Foundation.
I believe that you're looking for NSGetSizeAndAlignment:
Obtains the actual size and the aligned size of an encoded type.
const char * NSGetSizeAndAlignment (
const char *typePtr,
NSUInteger *sizep,
NSUInteger *alignp
);
Discussion
Obtains the actual size and the aligned size of the first data type represented by typePtr and returns a pointer to the position of the next data type in typePtr.
This is a Foundation function, not part of the base runtime, which is probably why you didn't find it.
UPDATE: Although you didn't initially mention that you're using Cocotron, it is also available there. You can find it in Cocotron's Foundation, in NSObjCRuntime.m.
Obviously, this is much better than rolling your own, since you can trust it to always correctly handle strings generated by its own runtime in the unlikely event that the encoding characters should change.
For some reason, however, it's unable to handle the digit elements of a method signature string (which presumably have something to do with offsets in memory). This improved version, by Mike Ash will do so:
static const char *SizeAndAlignment(const char *str, NSUInteger *sizep, NSUInteger *alignp, int *len)
{
const char *out = NSGetSizeAndAlignment(str, sizep, alignp);
if(len)
*len = out - str;
while(isdigit(*out))
out++;
return out;
}
afaik, you'll need to bake that info into your binary. just create a function which returns the sizeof and alignof in a struct, supports the types you must support, then call that function (or class method) for the info.
The program below shows you that many of the primitives are just one character. So the bulk of the function's implementation could be a switch.
static void test(SEL sel) {
Method method = class_getInstanceMethod([NSString class], sel);
const char* const type = method_copyReturnType(method);
printf("%s : %s\n", NSStringFromSelector(sel).UTF8String, type);
free((void*)type);
}
int main(int argc, char *argv[]) {
#autoreleasepool {
test(#selector(init));
test(#selector(superclass));
test(#selector(isEqual:));
test(#selector(length));
return 0;
}
}
and you could then use this as a starting point:
typedef struct t_pair_alignof_sizeof {
size_t align;
size_t size;
} t_pair_alignof_sizeof;
static t_pair_alignof_sizeof MakeAlignOfSizeOf(size_t align, size_t size) {
t_pair_alignof_sizeof ret = {align, size};
return ret;
}
static t_pair_alignof_sizeof test2(SEL sel) {
Method method = class_getInstanceMethod([NSString class], sel);
const char* const type = method_copyReturnType(method);
const size_t length = strlen(type);
if (1U == length) {
switch (type[0]) {
case '#' :
return MakeAlignOfSizeOf(__alignof__(id), sizeof(id));
case '#' :
return MakeAlignOfSizeOf(__alignof__(Class), sizeof(Class));
case 'c' :
return MakeAlignOfSizeOf(__alignof__(signed char), sizeof(signed char));
...
using the uvision IDE for STM32 development, I want to have some timer variables not initialized at startup. I have tried:
volatile unsigned int system_time __attribute__((section(".noinit")));
and
__attribute__((zero_init)) volatile int system_timer;
but nothing seems to work. Following the hints from elswhere, I have additionally checked NoInit at options/target/IRAM1.
Still, the variables are set to zero after reset.
Can anybody help?
You need to follow these steps.
declare your variable as follows:
volatile unsigned int system_time __attribute__((section(".noinit"),zero_init));
Then you have to use a scatter file to declare the execution section with the NOINIT attribute and use it with the linker.
example scatter file:
LR_IROM1 0x08000000 0x00080000 { ; load region size_region
ER_IROM1 0x08000000 0x00080000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 UNINIT 0x00000100 { ;no init section
*(.noinit)
}
RW_IRAM2 0x20000100 0x0000FFF0 { ;all other rw data
.ANY(+RW +ZI)
}
}
You have to check the address of that variable from .MAP file and use the The at keyword
allows you to specify the address for uninitialized variables in your C source files. The
following example demonstrates how to locate several different variable types using the at keyword.for example......
struct link {
struct link idata *next;
char code *test;
};
struct link idata list _at_ 0x40; /* list at idata 0x40 */
char xdata text[256] _at_ 0xE000; /* array at xdata 0xE000 */
int xdata i1 _at_ 0x8000; /* int at xdata 0x8000 */
char far ftext[256] _at_ 0x02E000; /* array at xdata 0x03E000 */
void main ( void ) {
link.next = (void *) 0;
i1 = 0x1234;
text [0] = 'a';
ftext[0] = 'f';
}
I hope it helps for solving your problem.