PDA

Επιστροφή στο Forum : Κάποιος με πολύ καλή εμπειρία στην C++;



xmaze
03-01-15, 23:34
Είναι σχετικό με ένα προηγούμενο πόστ μου, http://www.hlektronika.gr/forum/showthread.php?t=78851








Το θέμα είναι οτι όταν καλώ μία συνάρτηση απο μία άλλη κλάση ενώ δουλεύει μία χαρά, αλλάζω έναν πίνακα σε μιά struct και του βάζω λιγότερα δεδομένα, ξανα καλώ την συνάρτηση απο την άλλη κλάση και το πρόγραμμα καταρρέει με το σφάλμα.
Signal meaning :
Segmentation fault

Δοκίμασα να σβήσω απο τις συναρτήσεις όλο τον κώδικα, και μόνο με την κλήση την συνάρτησης χωρίς καμία άλλη ενέργεια το πρόγραμμα κάταρέει!

QVector<QStringList> results = candatabank->CANSignalList(B.id,CANDataFrameAs64bitUint,B.DLC); //ο κωδικάς της κλήσης.

Το αλαζω σε void results = candatabank->CANSignalList(); // και τυπώνω πχ HELLO WORLD.

αλλά μόνο με την κλήση το πρόγραμμα καταρέει!!

xmaze
05-01-15, 17:52
ξεχασα να βάλω το λινκ απο github με το προγραμμα !!

https://github.com/ntosis/openCANalysis

giannaras13
05-01-15, 18:20
ξεχασα να βάλω το λινκ απο github με το προγραμμα !!

https://github.com/ntosis/openCANalysis

οταν λες καταρρεει..εννοεις κλεινει το παραθυρο ?

xmaze
05-01-15, 18:38
οταν λες καταρρεει..εννοεις κλεινει το παραθυρο ?

Καταρέει τελείως , τερματίζεται απο το λειτουργικο FEDORA 20. Δες και screenshot.

Ενα CAN FRAME έχει απο 1 εώς 8 bytes σαν πληροφορία , εάν είναι με λιγότερο απο 8 τότε έρχεται αυτό το πρόβλημα. Γενικά το έχω προβλέψει και όλες τις loops τις εκτελώ πχ με το σκεπτικό i=0; i<DLC;

http://i58.tinypic.com/j7b2qf.png
Επίσης η κλάση που το κάνει αυτό καταρρέει μόνο με την κλήση της συνάρτησης

giannaras13
05-01-15, 20:51
Καταρέει τελείως , τερματίζεται απο το λειτουργικο FEDORA 20. Δες και screenshot.

Ενα CAN FRAME έχει απο 1 εώς 8 bytes σαν πληροφορία , εάν είναι με λιγότερο απο 8 τότε έρχεται αυτό το πρόβλημα. Γενικά το έχω προβλέψει και όλες τις loops τις εκτελώ πχ με το σκεπτικό i=0; i<DLC;

http://i58.tinypic.com/j7b2qf.png
Επίσης η κλάση που το κάνει αυτό καταρρέει μόνο με την κλήση της συνάρτησης
το λαθος αυτο γινεται γιατι χρησιμοποιηται λανθασμενα η μνημα και σου πεταει fault ειτε γιατι εχει memory protection η γιατι εκανες καποιο overflow..

εχεις δεσμευσει κανονικα 8 θεσεις,πριν το γεμισεις με loop?

xmaze
05-01-15, 22:11
έχω μια structure
struct {
......
uint8 Data[8];
}

και έπειτα γεμίζω τον πίνακα με μια λουπα for (int i=0; i<R.DLC;i++) {R.Data[i] = list[5+i].toUInt(&ok,16);}

Αυτή η κλαση που καταρέεει είναι πολύ μικρή και γενικά δεν έχει πολύ κώδικα, στην ουσία διαβάζει μια βάση δεδομένων.
Δεν έχει σχέση με πίνακες και μνήμες, λέγεται candatabank και αν θες μπορείς να την δέις και στο github.

giannaras13
05-01-15, 22:51
έχω μια structure
struct {
......
uint8 Data[8];
}

και έπειτα γεμίζω τον πίνακα με μια λουπα for (int i=0; i<R.DLC;i++) {R.Data[i] = list[5+i].toUInt(&ok,16);}

Αυτή η κλαση που καταρέεει είναι πολύ μικρή και γενικά δεν έχει πολύ κώδικα, στην ουσία διαβάζει μια βάση δεδομένων.
Δεν έχει σχέση με πίνακες και μνήμες, λέγεται candatabank και αν θες μπορείς να την δέις και στο github.

οτιδηποτε διαβαζεις απο βαση δεδομενων ο υπολογιστης το αποθηκευει σε προσωρινη μνημη και εκει γινεται overflow..
το R.dlc λογικα ειναι =8 γιατι αλλιως το integer δεν τα χωραει

xmaze
05-01-15, 23:30
Το πρόγραμμα επικοινωνεί με ένα usb donlge που διαβαζει το CAN Bus, το Data length code (DLC) λέει πόσα bytes περιέχει το frame δεν είναι ΠΟΤΕ πάνω απο 8.
Οταν το DLC είναι ίσο με 8 τότε όλα δουλεύουν ρολόι, διαβάζει την βάση δεδομένων και όλα είναι μία χαρά.

Εάν έρθει ένα frame με DLC=4 τότε το πρόγραμμα καταρέει. Αυτο που με προβληματίζει είναι οτι εάν αλλάξω την συνάρτηση την προβληματική σε μία κενή συνάρτηση, χωρίς βάσεις δεδομένων χωρίς τίποτα, πάρα μόνο θα έχει μέσα έναν i=i+1; Τότε πάλι εάν το DLC έιναι 4 και καλέσω την κενή συνάρτηση τότε καταρρέει πάλι.

Επίσης εάν δεν καλέσω αυτήν την συνάρτηση candatabank->CANSignalList όλα τα υπόλοιπα λειτουργούν άψογα!

giannaras13
06-01-15, 00:30
Το πρόγραμμα επικοινωνεί με ένα usb donlge που διαβαζει το CAN Bus, το Data length code (DLC) λέει πόσα bytes περιέχει το frame δεν είναι ΠΟΤΕ πάνω απο 8.
Οταν το DLC είναι ίσο με 8 τότε όλα δουλεύουν ρολόι, διαβάζει την βάση δεδομένων και όλα είναι μία χαρά.

Εάν έρθει ένα frame με DLC=4 τότε το πρόγραμμα καταρέει. Αυτο που με προβληματίζει είναι οτι εάν αλλάξω την συνάρτηση την προβληματική σε μία κενή συνάρτηση, χωρίς βάσεις δεδομένων χωρίς τίποτα, πάρα μόνο θα έχει μέσα έναν i=i+1; Τότε πάλι εάν το DLC έιναι 4 και καλέσω την κενή συνάρτηση τότε καταρρέει πάλι.

Επίσης εάν δεν καλέσω αυτήν την συνάρτηση candatabank->CANSignalList όλα τα υπόλοιπα λειτουργούν άψογα!
νικο δεν δοκιμαζεις αντι για στατικη αποδοση μνημης να βαλεις maloc?

troller_coaster
06-01-15, 01:28
Πού ακριβώς παίρνεις SIGSEGV;

Τρέξε το πρόγραμμα μέσα από debugger ώστε να δεις τις τιμές των μεταβλητών σου όταν κρασάρει. Θα καταλάβεις αμέσως τι συμβαίνει ή τουλάχιστον θα δεις τι ακριβώς πήγε να αναγνωστεί/γραφτεί σε σημείο που δεν είναι allocated.

Καλό είναι στη C++ να μην μπλέκεις malloc και free. Προτίμησε τους operators new και delete.

giannaras13
06-01-15, 02:17
Πού ακριβώς παίρνεις SIGSEGV;

Τρέξε το πρόγραμμα μέσα από debugger ώστε να δεις τις τιμές των μεταβλητών σου όταν κρασάρει. Θα καταλάβεις αμέσως τι συμβαίνει ή τουλάχιστον θα δεις τι ακριβώς πήγε να αναγνωστεί/γραφτεί σε σημείο που δεν είναι allocated.

Καλό είναι στη C++ να μην μπλέκεις malloc και free. Προτίμησε τους operators new και delete.

εννοειται οτι οταν εχεις constructor βαζεις new και σε void malloc..

xmaze
06-01-15, 11:09
Πού ακριβώς παίρνεις SIGSEGV;

Τρέξε το πρόγραμμα μέσα από debugger ώστε να δεις τις τιμές των μεταβλητών σου όταν κρασάρει. Θα καταλάβεις αμέσως τι συμβαίνει ή τουλάχιστον θα δεις τι ακριβώς πήγε να αναγνωστεί/γραφτεί σε σημείο που δεν είναι allocated.

Καλό είναι στη C++ να μην μπλέκεις malloc και free. Προτίμησε τους operators new και delete.

Το screen shot είναι απο τον debugger, δεν μπορώ να καταλάβω πού ακριβώς κολλάει!


εννοειται οτι οταν εχεις constructor βαζεις new και σε void malloc..
Εδώ σας χάνω λίγο,

CANdatabank::CANdatabank(QWidget *parent) :
QWidget(parent),
ui(new Ui::CANdatabank)
{
ui->setupUi(this);
}

ο contructor της κλάσσης και στην κλάσση mainwindow κάνω το εξής:
μέσα στον construtor της εχω αυτό => candatabank = new CANdatabank();
και στο header file

private:
Ui::MainWindow *ui;
//Console *console;
SettingsDialog *settings;
SendForm *sendform;
QSerialPort *serial;
CANdatabank *candatabank;

giannaras13
06-01-15, 11:29
Το screen shot είναι απο τον debugger, δεν μπορώ να καταλάβω πού ακριβώς κολλάει!


Εδώ σας χάνω λίγο,

CANdatabank::CANdatabank(QWidget *parent) :
QWidget(parent),
ui(new Ui::CANdatabank)
{
ui->setupUi(this);
}

ο contructor της κλάσσης και στην κλάσση mainwindow κάνω το εξής:
μέσα στον construtor της εχω αυτό => candatabank = new CANdatabank();
και στο header file

private:
Ui::MainWindow *ui;
//Console *console;
SettingsDialog *settings;
SendForm *sendform;
QSerialPort *serial;
CANdatabank *candatabank;

void ειναι οταν η συναρτηση δεν επιστρεφει τιμη..να σε ρωτησω κατι..το 5+i γιατι το εχεις?

xmaze
06-01-15, 12:15
void ειναι οταν η συναρτηση δεν επιστρεφει τιμη..να σε ρωτησω κατι..το 5+i γιατι το εχεις?

που; σε ποιο σημείο; γιατί δεν θυμάμαι που το έγραψα

giannaras13
06-01-15, 12:35
που; σε ποιο σημείο; γιατί δεν θυμάμαι που το έγραψα
εσωτερικα στον εκτελεσιμο κωδικα του loop

xmaze
06-01-15, 12:40
εσωτερικα στον εκτελεσιμο κωδικα του loop




R.id=list[0].toShort(&ok,16);
R.extended = list[1].toShort(&ok,10);
R.standart = list[2].toShort(&ok,10);
R.remote = list[3].toShort(&ok,10);
R.DLC = list[4].toShort(&ok,10);
for (int i=0; i<R.DLC;i++) {R.Data[i] = list[5+i].toUInt(&ok,16);}
Εννοείς μάλλον την τελευταία γραμμή, όπως έρχονται τα data απο το USB UART τα χωρίζω στο space σε μία list, και στο σημείο 5 + DLC βρίσκονται τα data του CAN frame!

troller_coaster
06-01-15, 23:58
Μπορείς να στείλεις το παραπάνω screenshot αλλά να φαίνονται οι τιμές των μεταβλητών; Η τιμή της Β φαίνεται γκρίζα. Μήπως δεν έχει αρχικοποιηθεί;

xmaze
07-01-15, 16:26
Μπορείς να στείλεις το παραπάνω screenshot αλλά να φαίνονται οι τιμές των μεταβλητών; Η τιμή της Β φαίνεται γκρίζα. Μήπως δεν έχει αρχικοποιηθεί;

http://i61.tinypic.com/n2g6mh.png

troller_coaster
07-01-15, 16:40
Έχουμε και λέμε:

Θέτεις τον pointer:

quint8 *add = (quint8 *) bits[0];

Τράτζικ! Ο δείκτης δείχνει στο 0 γιατί το bits[0] ήταν 0. Στη γραμμή 397 γίνεται evaluate (χωρίς να καταλαβαίνω πώς και γιατί είναι μόνο του) και πας να διαβάσεις από τη διεύθυνση 0. BANG!!! Μόλις σκότωσες το process!

Πιθανότατα στη γραμμή 396 ήθελες να κάνεις:

quint8 *add = (quint8 *) bits;

ή

quint8 *add = (quint8 *) &bits[0];

Δοκίμασε και πες μας.

xmaze
07-01-15, 16:51
το δοκίμασα, δεν φταεί αυτό...αυτό είναι σκουπίδι που έιχε μήνει απο δοκιμές, επρεπε να το είχα σβήσει!! αλλά παρόλλα αυτα δεν επηρεάζει το πρόγραμμα!

troller_coaster
07-01-15, 17:02
Επίσης το this είναι NULL, που σημαίνει πως οτιδήποτε data από το τρέχον instance προσπελάσεις θα χτυπήσεις στον τοίχο και πάλι. Χωρίς να έχω μπροστά μου όλον τον κώδικα υποθέτω ότι το candatabank είναι μέλος του αντικειμένου. Α, και ο parent είναι επίσης NULL, αλλά μάλλον γιατί προσθέτεις το root item.

xmaze
07-01-15, 17:54
Επίσης το this είναι NULL, που σημαίνει πως οτιδήποτε data από το τρέχον instance προσπελάσεις θα χτυπήσεις στον τοίχο και πάλι. Χωρίς να έχω μπροστά μου όλον τον κώδικα υποθέτω ότι το candatabank είναι μέλος του αντικειμένου. Α, και ο parent είναι επίσης NULL, αλλά μάλλον γιατί προσθέτεις το root item.

αυτό προσπαθω να καταλάβω, εκεινη την ώρα που έκανα το screen shot το αντιλήφθηκα. O κώδικας είναι στο Github, μπορείς να τον δείς. https://github.com/ntosis/openCANalysis
το this δέν ξέρω γτ είναι μηδέν. Γενικά όταν γίνεται κλήση της συνάρτησης CANSignalList, κλέινει το πρόγραμμα χωρίς να μπεί κάν στην συνάρτηση, δεν προλαβάινει δλδ να εκτελέσει τίποτα!

xmaze
08-01-15, 10:29
αυτό προσπαθω να καταλάβω, εκεινη την ώρα που έκανα το screen shot το αντιλήφθηκα. O κώδικας είναι στο Github, μπορείς να τον δείς. https://github.com/ntosis/openCANalysis
το this δέν ξέρω γτ είναι μηδέν. Γενικά όταν γίνεται κλήση της συνάρτησης CANSignalList, κλέινει το πρόγραμμα χωρίς να μπεί κάν στην συνάρτηση, δεν προλαβάινει δλδ να εκτελέσει τίποτα!

Η λύση βρέθηκε!!!! είμαι πολύ χαρούμενος!!

// Create a bit array of the appropriate size
quint8 bits[B.DLC*8];

// Convert from QByteArray to QBitArray
for(int i=0; i<s; ++i){
for(int b=0; b<8; ++b) {
int f=i*8+b; bool bit = (B.Data[i]&(1<<(7-b)));
if(bit) bits[f]=1; else bits[f]=0;
}}
quint64 CANDataFrameAs64bitUint=0;
for(int i=0; i<B.DLC*8;i++) {
//dec += pow(2,i)*bits[i];
CANDataFrameAs64bitUint |= ((bits[i])<<i);
}

results = candatabank->CANSignalList(B.id,CANDataFrameAs64bitUint,B.DLC);



Την ζημιά την έκανε αυτή η γραμή quint8 bits[B.DLC*8];
η λούπα έτρεχε για 64 φορές αλλά εάν ο πίνακας ήταν μικρότερος τότε αρχιζε και έβαζε μηδενικά παρακάτω!
Για καλή μου τύχη στης παρακάτω μνήμες ήταν ο ποιντερ this οπότε μηδένιζε και με την κλήση της συνάρτησης,
που στην ουσία ήταν
results = this-> candatabank->CANSignalList(B.id,CANDataFrameAs64bitUint,B.DLC);
κατέρεε!
ευχαριστώ πολύ!!