Hello, I work at the U.S. Department of Labor. I am a maintenance prorgrammer of C code, and the configuration management of this code in the past has been very spotty. When I took over this project, a CM tool was in place I have been doing corret checkins and checkouts, but the problems of the past bad management contiue to cause problems for me. There is a C screen I have been asked to modify to increase the allowed amount of a field. The code for that screen was never checked in to the CM tool, and I found it in the archived files of someone who left the project a couple of years ago. The code did not compile, but I was able to get it compiling correctly. When I run. however, it crashes with a core dump, and the dbx utility, reading the core dump, show that the error occurs on the main declaration.

main(argc)
int argc;

This was the original code. I have tried:

main(int argc)

and

main(int argc, char *argv[])

but they all crash on the main statement. I also tried removing the argc, just having main(), but that generated doxens of compiler errors. The error generated from the core dump, as read by the dbx utility, follows:

devextbfm mcpherson.john-/dhome/mcpherson.john/bfm-or/src $ dbx bsyrhd
For information about new features see `help changes'
To remove this message, put `dbxenv suppress_startup_message 7.7' in your .dbxrc
Reading bsyrhd
Reading ld.so.1
Reading libm.so.2
Reading libcurses.so.1
Reading libc.so.1
(dbx) debug -c core.bsyrhd.26957 bsyrhd
core file header read successfully
Reading libc_psr.so.1
program terminated by signal SEGV (access to address exceeded protections)
0x000182f8: main+0x047c:        stb      %g1, [%o5]
(dbx) where
=>[1] main(0x1, 0xffbff68c, 0xffbff694, 0x319e8, 0xff2900c0, 0x0), at 0x182f8

Any help with this problem is greatly appreciated.

Recommended Answers

All 11 Replies

Calling main(int c) is just plain wrong. Acceptable forms are main(void), main(), and main(int c, char[]). If you are trying to ask the system to evaluate the char[] argument using an int c that is not smaller than the size of the array, then you will get a SEGFAULT.

How much do you have set up as "static" from your main module?
How much is initialized before main runs?

I put an endwin() after the main call, and the screen is definitely crashing on main. I now have it as

main(int argc, char *argv[])

and I pass two arguments in the command line, but as I saw before, it crashes on the main statement. The declarations before the main statement are:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <curses.h>
#include <term.h>
/*globals*/
#define KDN 258
#define KUP 259
#define KL  260
#define KR  261
#define CR 13
#define SP 32
#define MORE TRUE
#define GETDAT TRUE
#define EDIT1 TRUE
#define EDIT2_6 TRUE
  /* regression updates */
#define BSYR TRUE
#define ALLUPD -1
#define QI   0
#define TWCR 1
#define UI   2
#define AWB  3
#define AWW  4
#define TAX  5
#define TOT  6
#define MWB  7
#define MTWB 8
#define HIQ  9
/* Fortran subroutines common vars (index as [j][i]) */
/**********************
 extern struct{
        double x[6][30];
        double xtxy[6][5];
        double b[6];
        double bstde[6];
        double tval[6];
        double bset[3][6];
        double stats[6];
        double ajrsq,ystde,ymse,xtra1,xtra2,syy;}regrs_;
*********************/
double svxtxy[6][5];
double coefs[6][4];
int iiaw[4],ieqtax[4],nobs=12,rgbsyr,ihiq;
FILE *upd;
FILE *tmp;
/*GLOBALS for window*/
WINDOW *win;
int ijlim[4] = {0,2, 0,3};
int xrych[2] = {0,7};
int xyold[2], xycur[2];
int i,j,x,y,key,imv,jmv,ijprv,xt,nqtrs=0,rpldgt,ytab,xtab=13,yfmt=21,ij;
int iskip=0,yskip=0,nskip=0,ncols,xlbl,xne;
double tbl[24][4];
double val,vtmp;
char vstr[20];
int rgbold[24] = {1,0,1};
  /* qtrly regrs vars output order in tbl */
  /*'QI','TWCR','UI','AWB','AWW','TAX','TOT','MWB','MTWB','TURQ' */
char *rghd[] = {" ","QI","TWCR","AWB","TAXTOT","YQI"};
int ihd[] = {0,0,0,4,3,0,0,2,4,4,3,2,0,0,3,0,0,1,5,2};
int iout[10] = {17,11,7,14,10,8,9,2,2,19};
double xin[4][10][15],yrxin[2][15],qia[15],tur[15];
static float vmax[22] = {100,4,100,9E4,2000,1E8,1E8,1E8,1E13,1E13,2000.,1E8,1E8,1E8,1000.,2.0,20.0,12.0,30.0,1E4,1E4,1E4};
static float vmin[22]; /* default 0 */
char *shofmt[] = {"%02.0lf","%-1.0lf","%02.0lf","%-5.0lf","%-.2lf","%-8.0lf","%-8.0lf","%-7.0lf","%-.0lf","%-.0lf","%-.2lf","%-7.0lf","%-7.0lf","%-7.0lf","%-
.2lf","%-1.0lf","%-5.2lf","%-.2lf","%-.2lf","%-.0lf","%-.0lf","%-.0lf"};
/* edit format includes an extra space for decimal values */
char *edfmt[] ={"%2lf","%1lf","%2lf","%5lf","%6lf","%8lf","%8lf","%7lf","%12lf","%12lf","%7lf","%7lf","%7lf","%7lf","%7lf","%2lf","%5lf","%6lf","%5lf","%7lf"
,  "%5lf","%5lf"};
/* end globals*/
#include "mvc7.cfn"
#include "nerrmsg2.cfn"
#include "rplnum2.cfn" /* uses global index ij (not i) for fmts, vmax */
#include "rpldgt2.cfn"
#include "center.cfn"
#include "prtscr.cfn"
  /* for regressions */
#include "regrsh.h"
#include "ultxt.cfn"
#include "rgout.cfn"
#include "mxpfmt.cfn"
#include "findhd.cfn"
#include "rgqi.cfn"
#include "rgtwhq.cfn"
#include "rgawb.cfn"
#include "rgtxto.cfn"
#include "rgtur.cfn"
#include "invxtx5.cfn"
#include "mkxtxy5.cfn"  

I don't know if this extra information will help or not. Thanks for your assistance.

Since it's legacy code, either I have to dive in to every include to find it or use the old binary search method.

Remember I take it you are a seasoned programmer and just need to chat about how other programmers narrow it down.

If this was mine I'd check the compiler output for warnings and errors. For gcc, I use the -Wall command. It's kicked around at https://stackoverflow.com/questions/11714827/how-to-turn-on-literally-all-of-gccs-warnings for extra switches.

Also, be sure this code is run through LINT.

Once in a while I encounter a programmer that does not believe apps should be warning and error free or pass LINT. They tend to have the most devilish of problems.

I used the -Wall optoin on the gcc compile, and some of the warnings indicated issues, and I fixed those problems. The only warnings I get now are either implicit function declaration, or unused variables, and those will not cause a crash. However, the screen still crashes on main. I ran LINT, and a lot of output scrolled on my screen, and unfortunately scrolled off. I did the redirection to get the output from LINT into a file called temp, but the out will not rediect. The LINT man page I found on google stated that redirection should be enough, but several tries I did would not redirect the output to a file. I am running on a SUn Sparc, using solaris 10. Yes, it is an old system we are working on upgrading, but I have to keep developing on this system in the meantime. The different tries have made to redirect the output are:

lint -# bsyrd.c > temp

lint -# bsyrd.c Output=temp

lint -# Output=temp bsyrhd.c

lint -# Output=temp bsyrhd.c > temp

I am using verbose mode since I need to look at and fix every possible problem in this legacy code to get it working. Any help in getting the output to redirect to a file is appreciated.

Unused can be an issue. If they are declared in some bum way, well, when the app starts up the allocation can cause a fault.

SUN. Wow, blast from the past. I used those what in 1990? And later wrote install documents (did some tech writing) in the mid 90's.

Anyhow I'm very rusty on SUN OS but even if redirection doesn't work the output should be on the terminal window which you can copy and paste into the document you are using.

Also, isn't there more than > ? What about 2> ?

The declaration of main() is not illegal, but it may not be complete. For pre-ANSI C, the usual declaration is

        main(argc,argv)
        int argc;
       char **argv;
       {
           /* Main */

or some variant.

What DBX is telling you in the backtrace is that the error occured in main(), not at the function declaration. The error occurred at main+0x047c, which is some distance from the function entry.

It looks like you did not compile with debug information. Use the -g option and re-run your program.

Re: Lint. Using lint on very old legacy code is not likely to be very useful. It is going to flag many statements as questionable. (Even with good quality code, lint often generates many messages.) You can spend a huge amount of time trying to make lint happy, very little of which will actually fix any bugs.

Re: Lint. As I've worked far too many systems with bugs that were traced to lines that Lint complained about, you can make bet on my view here.

Re: WALL and compiler warnings. After too many trips overseas to work with companies there, I used to pass on a warning or two. The cost of the trips were so high and in the end the issues were again traced to either design on warnings the compiler issued.

As to genenerating many messages, after a while you know which to focus on and here we are again, going over an app that has nearly unexplainable crashes.

After too many lost opportunites and upset clients you can take a second bet where I stand on code analysis.

Thanks to everyone for your suggestions. Since I have been compiling these screens with the gcc compiler, I downloaded the gdb debugger and used it instead of dbx, compiling with the -g option. The problem was not with the main() statement, but later on when the original coder of this screen tried to modify a string literal, which you cannot do. Once I cleaned up the places where that modification was attempted, the screen runs fine. Thanks again to everyone for their help.

commented: Thanks for the report back. Literally good news. +12
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.