What gdb commands should I use to narrow down where in label 'main' did I get the segmentation fault?

0

Here's my assembly code and my main subroutine. Here are my macros and constants:

             .text
fmt:         .string "x \t\t ln(x)\n"
sfmt:        .string "%.10lf \t %.10lf\n"
error:       .string "Error"
filename:    .string "input.bin"

             .data
LIM:         .double 0r1.0E-13
zero:        .double 0r0.0
one:         .double 0r1.0
half:        .double 0r0.5

define(i_r,w19)
define(j_r,w20)
define(n_r,w21)
define(fd_r,w22)
define(ln_x,d8)
define(cur_term,d24)
define(n_read,x25)
define(x_j,d26)

BUF_SIZE = 98*8
AT_FDCWD = -100
O_RDONLY = 0
buf_s = 16

          .bss
x_arr:    .skip   BUF_SIZE

fp        .req    x29
lr        .req    x30

          .balign 4
          .global main

Here's my main subroutine:

main:
       stp    fp,lr,[sp,-16]!
       mov    fp,sp

       ldp   fp,lr,[sp],16
       ret

I already used gdb however, it only points out that the SIGSEGV signal came from 0x0000000000420358 in main(). How can I narrow down where in 'main' this signal comes from? P.S I only know the basics of GDB.

GDB Stuff:(update)

(gdb) x/i $pc
=> 0x420358:    .inst   0x00000000 ; undefined

I don't know if this helps but this is the C version THAT WORKS. I am converting it to assembly because thats what I need to hand in. Also we cannot use any types of converter since thats considered cheating.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>                                                                 //Used for the keyword for flags and other predefined values for the argument on openat,etc.

#define LIM         1.0e-13                                                     
#define DOUBSIZE    100                                                         //There are 97 double values in the binary file
#define buf_size    98*8                                                        
double x[DOUBSIZE];
int main() {
    register int i = 1,j = 0,fd = openat(AT_FDCWD,"input.bin",O_RDONLY);    //int fd = openat(int dirfd,const char *pathname (basically a string),int flags,mode_t mode);
    register double ln_x = 0.0,cur_term;
//double *x;        //(only local variable)                                         //(a local variable so it must be in the stack)only assuming there are 32 double precision values in the binary file
    register long n_read = read(fd,&x,buf_size);                            //reads in 8 bytes(lost the double x[...] in this line since x is now pointing at the buffer

    if(fd == -1) {
        printf("Error!");
        return 0;
    }

    if(n_read == -1) {                                                          //Error checker
        printf("Error!");                           
        return 0;                                   
    }                                           

    printf("x \t\t ln(x)\n");                                                   //The header of the thing to be printed

    while(j < (buf_size/8)) {                                                   //note that it is implied that EOF = -1 in C
        if(x[j] <= 0.5) {                                                       //if x is less than or equal to 1/2,go to the next double value(assuming I don't know values in the bin file)
            j++;
            i = 1;
            continue;
        }

        cur_term = (1.0/i) * (pow((double)((x[j]-1.0)/(x[j])),i));
        ln_x += cur_term;

        while(cur_term >= LIM) {                                                //continue to accumulate terms until the absolute value of the term is less than 1.0E-13
            i++;                                                                //follows the pattern of the series.
            cur_term = (1.0/i)*(pow((double)((x[j]-1.0)/(x[j])),i));            //since it should start with x[1]
            ln_x += cur_term;                                                   //adds the new term to previous ln(x) value
        }

        printf("%.10lf \t %.10lf\n",x[j],ln_x);                                 //prints the current value of ln(x) and x
        j++;                                                                    //manages which x double value will be used next
        i = 1;
        ln_x = 0.0;
    }

    close(fd);
    return 0;
 }
c
assembly
64-bit
arm64
armv8
asked on Stack Overflow Dec 5, 2019 by Elo • edited Dec 6, 2019 by Elo

1 Answer

3

Turns out your main is in the .bss section, not .text where it belongs, so it can only contain all-zero bytes. (And it won't be executable).

GDB normally only wants to disassemble code in the .text section so that also explains GDB being weird.

This is why you should reduce your code to a MCVE (Minimal / complete / verifiable example) to make it as small as possible while still containing the problem.

answered on Stack Overflow Dec 6, 2019 by Peter Cordes

User contributions licensed under CC BY-SA 3.0