[закрыто] x64: мне качественно отстреливает ногу

yolki

Винда.

struct S {
...
LPCWSTR pwszName;
...
};
...
struct S *s=GetSFromOutside;
size_t len;
len=wcslen(s->pwszName); /// *
...

Смотрю отладчиком строку (*).
На входе:

s 0x00000000001a2fe0 {... pwszName=0x00000000001a2418 ... }

Идём внутрь wcslen

size_t __cdecl wcslen (
const wchar_t * wcs
)
{
const wchar_t *eos = wcs;
while( *eos++ ) ;
return( (size_teos - wcs - 1) );
}

смотрим отладчиком wcs:

+ wcs 0x001a241800000000 <Bad Ptr> const wchar_t *

WTF?
куда можно копать?

yolki

если глянуть disassembly:

len=wcslen(s->pwszName;
0000000140013B87 mov rax,qword ptr [s]
0000000140013B8C mov rcx,qword ptr [rax+0Ch]
0000000140013B90 call wcslen (1404C2870h)

после выполнения mov rcx, qword ptr [rax+0Ch] имеем в rcx: 0x001a241800000000
Щ_щ

apl13

LPCWSTR pwszName;
Вот за это люблю FailAPI.

elenangel

из вне, значит из сети?
похоже на разную endianness

Maurog

куда можно копать?
это может быть нарушение ODR
структура в разных единицах трансляции определена по-разному
внимательно посмотри какие макросы используются в определении структуры. эти макросы могут развернутся в разные вещи в разных либах\исходниках

yolki

да не, отлаживаю в виртуалке
компилируем на семёрке x86. запускаем из-под rdb на win2003 R2 SP2 x64
к вопросу - почему +0Ch?

typedef struct S {
DWORD ...;
LPCSTR ...;
LPCWSTR pwszName;
DWORD ...;
...

DWORD -4 байта, LPCSTR - 8 (64 бит же!?) итого - 12 = 0xC
ну не может же в самом деле или sizeof(LPCSTR) = 4?

yolki

так. поставил принудительный alignment на 8 байт в структурах - заработало. видимо, тут промашка была.
проверю гипотезу sizeof(LPCSTR)==4 на 64 битной платформе

apl13

проверю гипотезу sizeof(LPCSTR)==4
http://msdn.microsoft.com/en-us/library/cc230350.aspx

yolki

на 64-битной платформе?
короче надо будет найти, кто забыл сделать #pragma pop на #pragma push pack(4)
и подвесить за йайца

apl13

на 64-битной платформе?
Технологии Майкроусофт™.

Dasar

4 байта он только в 32-битной системе
Changes to Windows data types
Here is a list of the changes to data types between 32 and 64-bits:-
All handles now qwords not dwords
eg.
HACCEL, HINSTANCE, HBRUSH, HBITMAP
HCOLORSPACE, HCURSOR, HDC, HFONT
HICON, HINSTANCE, HKEY, HLOCAL
HMENU, HMODULE, HPEN, HPALETTE, HWND
(and others starting with H)
exceptions:- HRESULT, HFILE which remain dwords, and HALF_PTR (see below)
All pointers now qwords not dwords
eg.
LPCSTR, LPCTSTR, LPLONG, LPSTR
(and others starting with LP)
PBOOL, PHANDLE, PHKEY, PVOID
(and others starting with P)
DWORD_PTR, ULONG_PTR, UINT_PTR
(and others ending with _PTR)
and LRESULT
exceptions:- HALF_PTR, and UHALF_PTR which are now dwords instead of a word and POINTER_32 which remains a 32-bit pointer
http://www.godevtool.com/GoasmHelp/64bits.htm

apl13

Ты какую-то немножко не мелкософтную ссылку дал.

Dasar

первую из гугла. На msdn-е тоже есть, но надо будет чуток поискать.

vik1538

LPCSTR этож указатель, все указатели 8 байт на 64бита и 4 на 32бита.

vall

DWORD ...;
LPCSTR ...;
LPCWSTR pwszName;
если DWORD 32-бита то после него 32-бита дырка выравнивания

yolki

спасибо, я уже поправил злополучный #pragma pack

vall

у тебя разные объектники собирались с разным выравниванием?
да уж, качественно отстрелил ногу
Оставить комментарий
Имя или ник:
Комментарий: