Problem description:
GNU C and C++ compilers generate a one byte ahead source file name in the ELF
executable symbol table.

Problem demonstrator:
$ uname -a
HP-UX persee B.11.31 U ia64 4171193755 unlimited-user license
$ export PATH=$PATH:/usr/local/bin
$ gcc -v
Using built-in specs.
Target: ia64-hp-hpux11.31
Configured with: ../gcc/configure 
Thread model: posix
gcc version 4.2.3
$ cat trace.c
#include <uwx.h>
#include <uwx_self.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <string.h>


char *trace(uint64_t rp){
    struct uwx_env              *env = NULL;
    struct uwx_self_info        *info = NULL;
    char                        *executable;
    int                         ret;
    struct uwx_symbol_cache     *cachep=NULL;
    char                        *funcp=NULL;
    char                        *ifuncp=NULL;
    uint64_t                    offsetp=0;
    char                        *srcfilep=NULL;
    int                         linenump=0;
    int                         inline_contextp=0;
    struct load_module_desc     desc;
    uint64_t                    handle;
    static char                 formatted_text[80];

    handle=dlmodinfo(rp,&desc,sizeof(desc),NULL,
                      0,0);
    if (!handle){
        fprintf(stderr,"%s\n",dlerror());
        exit(EXIT_FAILURE);
    }
    executable=dlgetname(&desc,sizeof(desc),NULL,0,0);
    if (!executable){
        fprintf(stderr,"%s\n",dlerror());
        exit(EXIT_FAILURE);
    }

    env = uwx_init();
    info = uwx_self_init_info(env);
    ret = uwx_self_init_context(env);
    rp -= desc.text_base;
    ret  = uwx_find_source_info(env, &cachep,
                               executable, rp, 0,0, &ifuncp,&funcp,&offsetp,
                               &srcfilep,&linenump,&inline_contextp);
    if (ret == UWX_ERR_NOSYM){
        strcpy (formatted_text,"??? ");
    }
    if (ret == UWX_OK && srcfilep != NULL && linenump != 0){
        sprintf(formatted_text,"%s:%u ",srcfilep,linenump);
    }
    if (ret == UWX_OK && srcfilep != NULL && inline_contextp != 0){
        sprintf(formatted_text,"%s:%u ",srcfilep,inline_contextp);
    }
    uwx_release_symbol_cache(env,cachep);
    uwx_self_free_info(info);
    uwx_free(env);
    return formatted_text;
}
$ cat backtrace.c 
#include <uwx.h>
#include <uwx_self.h>
#include <ulimit.h>
#include <stdio.h>
#include <stdlib.h>

/*
 * On HP-UX, this code must be linked with libunwind.so
 */
int
backtrace(uint64_t *buffer, int size)
{
    struct uwx_env              *env = NULL;
    struct uwx_self_info        *info = NULL;
    uint64_t                    rp;
    int                         ret;
    int                         i,level=0;
    uint64_t                    *tmp=buffer;

    env = uwx_init();
    info = uwx_self_init_info(env);
    ret = uwx_register_callbacks(env, (intptr_t)info,
                uwx_self_copyin, uwx_self_lookupip);
    ret = uwx_self_init_context(env);
    if(ret != UWX_OK) {
        fprintf(stderr, "uwx_self_init_context() got error %d\n", ret);
        exit(1);
    }
    do {
        ret = uwx_step(env);
        if (ret != UWX_OK)
            break;
        ret = uwx_get_reg(env, UWX_REG_IP, &rp);
        tmp[level]=rp;
        level++;
#ifdef DEBUG 
      {      
        char *modp=NULL;
        int offsetp=0;
        uwx_get_source_info(env,NULL,&modp,&offsetp,NULL);
        if (modp) fprintf(stderr,"%s:%u\n",modp,offsetp);
      }      
#endif       
    } while((level < size) && (ret == UWX_OK));
#ifdef DEBUG
    for (i=0;i<level;i++) fprintf(stderr,"tmp[%d]=0x%x\n",i,tmp[i]);
#endif
    uwx_self_free_info(info);
    uwx_free(env);
    return(level);
}
$ cat foo.c 
#include <sys/types.h>
#include <stdio.h>
extern int backtrace(uint64_t *buffer,int size);
extern char *trace(uint64_t pc);

#define SIZE 100

int foo(uint64_t *buffer)
{
     int size;
     size = backtrace(buffer,SIZE);
     return size;
}
main()
{
     int i,size;
     uint64_t buffer[SIZE];
     size=foo(buffer);
     for (i=0;i<size;i++){
          char *cp=trace(buffer[i]);
          printf("buffer[%d]=%s\n",i,cp);
     }
}
$ cc -c trace.c
$ cc -c backtrace.c 
$ #
$ # Compiled with HP-UX bundled compiler.
$ #
$ cc -o foo trace.o backtrace.o -lunwind foo.c 
$ ./foo                                        
buffer[0]=foo.c:11 
buffer[1]=foo.c:18 
buffer[2]=???
$ #
$ # compiled with the latest gcc for HP-UX as downloadable from
$ # http://hpux.connect.org.uk/
$ #
$ gcc -g -o foo trace.o backtrace.o -lunwind foo.c 
$ ./foo
buffer[0]=oo.c:11 
buffer[1]=oo.c:18 
buffer[2]=??? 
$


-- 
           Summary: when compiling -g gcc and g++ are one byte ahead for the
                    source file name
           Product: gcc
           Version: 4.2.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: Philippe dot Vouters at laposte dot net
  GCC host triplet: HP-UX persee B.11.31 U ia64 4171193755 unlimited-user
                    license
GCC target triplet: HP-UX persee B.11.31 U ia64 4171193755 unlimited-user
                    license


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39562

Reply via email to