32 비트 컴파일 vs 64 비트 컴파일
안녕하세요.
요즘 프로세스가 사용하는 포트를 찾는 프로그램 개발하고 있는데
실행시 에러가 납니다.
환경은 Solaris 8 sparc 64비트 커널이구요
소스는 www.sunfreeware.com에 있는 lsof의 소스을 받아서
분석을 해서만들고 있습니다.
lsof의 소스를 가져와서 컴파일 해보니 반드시 "-m64" (64비트 컴파일)
옵션을 주어야만 컴파일이 되어서 실행이 되더군요.
문제는 저희 프로그램이 기본적으로 32비트로 컴파일이 되어있기때문에
-m64 옵션을 빼고 32비트로 컴파일을 해야 되는 상황입니다.
그래서 -m64을 빼고32비트로 컴파일을 해보고 실행화일까지 만들어지만
nlist 라는 함수에서 계속 실패을 하면서 프로그램이 진행이 되지 않습니다.
그래서 lsof에서 nlist 그부분만 떼어네서 나름대로 프로그램을 테스트 해보았는데
역시 마찬가지로 "-m64" 옵션을 주어야만 되더군요..
왜 그럴까요?
제 생각에는 nlist 함수가 커널에서 file name list을 가져오는데
커널이 64비트구조라서 32비트로 컴파일된 실행화일이므로 실패하는것으로 추측되어지지만 확실한 물증(?)이 없군요. -.-;
이런한 경험이 있으신 분이있나요?
또 lsof을 32비트로 컴파일해서 성공하신분(실행까지) 있으시거나
참고할만한 사이트을 아시면 고맙게습니다.
다음 nlist의 테스트 프로그램 입니다.
------------ 테스트 --------------------
#gcc -g -m64 nlist_test.c -lelf --> 64비트로 컴파일
#./a.out
# success - nlist return value = 0
#gcc -g nlist_test.c -lelf --> 32비트로 컴파일
#./a.out
#fail - nlist return value = -1, errno = 0
------------- 소스 -----------------------
#include <stdio.h>
#include <nlist.h>
#include <errno.h>
#include <stdlib.h>
struct drive_Nl
{
char *nn;
char *knm;
};
struct nlist *Nl;
char *Nmlst;
struct drive_Nl Drive_Nl[] = {
{ "arFid", "afs_rootFid" },
{ "avops", "afs_vnodeops" },
{ "Avops", "Afs_vnodeops" },
{ "avol", "afs_volumes" },
{ "auvops", "auto_vnodeops" },
{ "cvops", "cachefs_vnodeops" },
{ "clmaj", "clonemaj" },
{ "fdops", "fdvnodeops" },
{ "fvops", "fifo_vnodeops" },
{ "hvops", "hsfs_vnodeops" },
{ "lvops", "lo_vnodeops" },
{ "mntops", "mntvnodeops" },
{ "mvops", "mvfs_vnodeops" },
{ "nvops", "nfs_vnodeops" },
{ "n3vops", "nfs3_vnodeops" },
{ "nmvops", "nm_vnodeops" },
{ "nproc", "nproc" },
{ "pdvops", "pcfs_dvnodeops" },
{ "pfvops", "pcfs_fvnodeops" },
{ "prvops", "prvnodeops" },
{ "sgvops", "segvn_ops" },
{ "sckvops", "sock_vnodeops" },
{ "spvops", "spec_vnodeops" },
{ "tvops", "tmp_vnodeops" },
{ "uvops", "ufs_vnodeops" },
{ "vvops", "vx_vnodeops" },
{ "vvfops", "fdd_vnops" },
{ "vvfcops", "fdd_chain_vnops" },
{ "dvops", "door_vnodeops" },
{ "kbase", "_kernelbase" },
{ "kasp", "kas" },
{ "", "" },
{ NULL, NULL }
};
int main()
{
struct drive_Nl *dp;
int i, n, result;
Nmlst="/dev/ksyms";
for (dp=Drive_Nl, n = 0; dp->nn; dp++, n++)
;
if (n < 1)
{
printf("can't calculate kernel name list length\n");
}
if (!(Nl = (struct nlist *)calloc((n + 1), sizeof(struct nlist))))
{
printf("can't allocate bytes to kernel name list structure\n");
}
for (dp=Drive_Nl,i = 0; i < n; dp++, i++)
{
Nl[i].n_name = dp->knm;
}
result = nlist(Nmlst, Nl);
if (result == -1)
{
printf("fail - nlist return value = %d, errno =%d\n",result,errno);
}
else
{
printf("success - nlist return value = %d\n",result);
}
return 0;
}
------------------------------------------------------------------
흠 이렇게 한번 수정해보겠어요
수정전
수정후
지금 봐서는 0인 값이 return 되면 문제가 될만한 소지가 있네요.
정확하게 -1이 에러니 -1일때 저렇게 할수 있도록 코드를 변경해 보세요
그럼
수정을 해서 체크을 해보니....
오류을 지적해주셔서 고맙습니다.
수정을 해서 컴파일을 해도 결과는 같습니다.
-m64로 옵션을 주고 컴파일하면 nlist의 리턴값이 "0" 이고
아무 옵션을 주지 않고 컴파일하면 nlist의 리턴값이 "-1" 이 나옵니다.
#gcc -g -m64 nlist_test.c -lelf --> 64비트로 컴파일
#./a.out
# success - nlist return value = 0
#gcc -g nlist_test.c -lelf --> 32비트로 컴파일
#./a.out
#fail - nlist return value = -1, errno = 0
그리고 실패했을때 이함수는 따로 errno 변수에 값을 담지 않는것 같습니다.
즐거운 주말 보내세요
댓글 달기