PDA

View Full Version : Segmentaiton Fault Error Difficulty



marinskye
8th April 2016, 17:54
Hello,

I'm running into a bit of trouble when trying to run a piece of code. Overall, what I'm trying to do is measure a signal from an ADC, process it and then display it on the monitor. The latter half is fairly straight forward, but before trying I'm trying to just configure the ADC process. The code is to run on a Raspberry Pi, with a Linux OS. I have code anyway which does sample the signal correctly using the ADC in C++, however when converting it to the format for Qt, I seem to get a Segmentation error. Now, from reading the forums here I've found that this occurs when the program tries to access a piece of memory that doesn't belong to it – which is fairly confusing as this problem does not occur when the same arguments are passed through it in c++. Most commonly this seems to be from pointers not being initialised or being initialised incorrectly. Through the debugging process, I've not been able to find any more information other than where the error occurs – which is why I'm now asking you guys here.

The error I get is:
Program received signal SIGSEGV, Segmentation fault.
0x00011f24 in gz_clock_ena(int, int) ()

Therefore it seems the error occurs in a function titled gz_clockena(). Using backtrace didn't really give any more information, other than to say where the error occured. This error occurs in an implementation file titled 'adcreader.cpp'.

The relevant parts of this code, pertaining to the problem is:


1 #include "adcreader.h"
2 #include <QDebug>
3 #include <QtCore>
4 #include "gpio-sysfs.h"
5 #include <fcntl.h>
6 #include <sys/ioctl.h>
7 #include <linux/types.h>
8 #include <linux/spi/spidev.h>
9 #include <assert.h>
10 //#define GZ_CLK_5MHz 0
11 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
12
13 #define MAX_SAMPLES 65536
14
15 ADCreader::ADCreader()
16 {

72 fprintf(stderr, "spi mode: %d\n", mode);
73 fprintf(stderr, "bits per word: %d\n", bits);
74 fprintf(stderr, "max speed: %d Hz (%d KHz)\n", speed, speed/1000);
75
76 // enable master clock for the AD
77 // divisor results in roughly 4.9MHz
78 // this also inits the general purpose IO
79 gz_clock_ena(GZ_CLK_5MHz,5); .......
80 }


In this same implementation file there is a function ADCreader::run() - which is the thread I'm running.
I initialised it in the main.cpp file as so:



#include <QCoreApplication>
#include "adcreader.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);

ADCreader adcr;
adcr.start();



return a.exec();
}


The problem definitely occurs in the gz_clock_ena function as the three 'fprintf' lines are output.
From what I read before about this error occuring when trying to access a memory location it doesn't have access to, I changed the values of the arguments. However this had no luck, and the same error occured.

The implementation of this function is in a file called 'gz_clk.cpp'. The relevant parts of the code for this is:


29 int gz_clock_ena(int speed, int divisor) {
30 int speed_id = 6;
31 if (speed < GZ_CLK_5MHz || speed > GZ_CLK_125MHz) {
32 printf("gz_clock_ena: Unsupported clock speed selected.\n");
33 printf("Supported speeds: GZ_CLK_5MHz (0) and GZ_CLK_125MHz (1).");
34 exit(-1);
35 }
36 if (speed == 0) {
37 speed_id = 1;
38 }
39 if (divisor < 2) {
40 printf("gz_clock_ena: Minimum divisor value is 2.");
41 exit(-1);
42 }
43 if (divisor > 0xfff) {
44 printf("gz_clock_ena: Maximum divisor value is %d.", 0xfff);
45 exit(-1);
46 }
47 if (bcm2835_init() !=1) {
48 printf("gz_clock_ena: Failed to initialize I/O\n");
49 exit(-1);
50 }
51 usleep(5);
52 bcm2835_gpio_fsel(RPI_GPIO_P1_07, BCM2835_GPIO_FSEL_ALT0);
53 *(bcm2835_clk + 0x1C) = 0x5A000000 | speed_id; // GPCLK0 off
54 while (*(bcm2835_clk + 0x1C) & GZ_CLK_BUSY) {} // Wait for BUSY low
55 *(bcm2835_clk + 0x1D) = 0x5A002000 | (divisor << 12); // set DIVI
56 *(bcm2835_clk + 0x1C) = 0x5A000010 | speed_id; // GPCLK0 on
57 return 0;
58 }



Naturally I would have thought that the error would have occured because the argument Gz_CLK was not initialised correctly, but it was in the header file for this implementation. Also as mentioned previously, I changed the values of the arguments in the function 'gz_clock_ena(GZ_CLK_5MHz,5);' to make sure this wasn't the root of the problem.

I've not been able to find any information that can get me close to solving the problem, so any help from anybody here as an indication would be greatly appreciated.

Many thanks.

d_stranz
8th April 2016, 18:23
You seem to be very confused about the differences between compiling, linking, and running a program.

If your constant GZ_CLK_5MHz was not defined, your code would not have compiled, and there would be nothing to link or run.

If you didn't include the proper libraries when linking (as in your previous post), then your program won't link and there will be nothing to run.

Your current problem appears to be a run-time error. You are accessing memory locations defined by some pointer named "bcm2835_clk". Where is this pointer initialized? If it isn't being initialized, then it is either NULL or garbage, but in either case trying to access its contents via *(bcm2835_clk +0xXX) type statements will blow up.

marinskye
8th April 2016, 21:49
Hi there, thanks for taking the time to reply.

Apologies for the lack of terminology, I am new to programming as well as Qt.

Thanks for pointing to the possible source of the error. The pointer "bcm2835_clk" is actually defined as: "extern volatile uint32_t *bcm2835_clk;", in a library I installed known as BCM2835 which allows access to GPIO functions. However, that is the only mention of it. I am not sure of the nuaunces of the code in 'gz_clk.cpp' specifically, as that was given as a working example.


To avoid this error, would it bcm2835_clk need to be given a value, rather than just being defined as "extern volatile uint32_t *bcm2835_clk;"

anda_skoa
9th April 2016, 10:52
You probably need to initialize the library.
Most C libraries that maintain a state of some sort have some kind of init function.

Cheers,
_