operator[] bei std::vector
-
Hallo,
machen übliche Compiler - ich verwende gcc - im debug modus für den operator[]
bei std::vector eigentlich einen Range-Test?Gruß,
Newbie19
-
schau dir einfach den code an
-
VC ja
-
ja schrieb:
VC ja
Auch bei Release? Auch bei _SECUREL_SCL == 0?...
-
Kommt drauf an, was für einen Debugmodus Du meinst. Normalerweise bedeutet das, dass Optimierungen ausgeschaltet werden und Debuginformationen "-g" eingefügt werden, wohingegen im Releasemodus Optimierungen eingeschaltet werden und "-DNDEBUG" benutzt wird, welches u.a. auch
asserts ausschaltet.Wenn Du das mit "Debugmodus" meinst, dann ist die Antwort nein. Es findet keine Bereichsprüfung statt.
Es gibt aber noch extra einen Debugmodus für die Standardbibliothek. Diesen kannst Du mit -D_GLIBCXX_DEBUG aktivieren, wenn Du Dein Programm kompilierst. Dann werden insgesamt sehr sehr viele Überprüfungen gemacht -- siehe http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html. Auch operator[] testet dann die Indizes auf Gültigkeit. Wenn da etwas nicht passt, wird das Programm abgebrochen.
Hier ein Beispiel:
#include <iostream> #include <vector> void foo(std::vector<int> const& t) { std::cout << t[3] << '\n'; } int main() { std::vector<int> t; t.push_back(23); t.push_back(42); t.push_back(99); try { foo(t); } catch (...) { std::cout << "yay!\n"; } }Kompilieren und im Debugger laufen lassen:
kk@home:/tmp$ g++ -D_GLIBCXX_DEBUG -g -otest test.cpp kk@home:/tmp$ gdb ./test GNU gdb (GDB) 7.1-ubuntu Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i486-linux-gnu". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /tmp/test...done. (gdb) run Starting program: /tmp/test /usr/include/c++/4.4/debug/vector:272:error: attempt to subscript container with out-of-bounds index 3, but container only holds 3 elements. Objects involved in the operation: sequence "this" @ 0x0xbffff3e4 { type = NSt7__debug6vectorIiSaIiEEE; } Program received signal SIGABRT, Aborted. 0x0012d422 in __kernel_vsyscall () (gdb) backtrace #0 0x0012d422 in __kernel_vsyscall () #1 0x00293651 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64 #2 0x00296a82 in *__GI_abort () at abort.c:92 #3 0x00180f52 in __gnu_debug::_Error_formatter::_M_error() const () from /usr/lib/libstdc++.so.6 #4 0x080490c8 in std::__debug::vector<int, std::allocator<int> >::operator[] ( this=0xbffff3e4, __n=3) at /usr/include/c++/4.4/debug/vector:272 #5 0x08048c2d in foo (t=...) at test.cpp:6 #6 0x08048d06 in main () at test.cpp:16 (gdb)Du kannst Dich aber darauf einstellen, dass das Programm ohne Optimierungen und mit den ganzen Zusatzüberprüfungen sehr langsam läuft.
kk
-
krümelkacker schrieb:
Es gibt aber noch extra einen Debugmodus für die Standardbibliothek. Diesen kannst Du mit -D_GLIBCXX_DEBUG aktivieren, wenn Du Dein Programm kompilierst.
Danke Krümelkacker!
Genau so etwas meinte ich!
-
theta schrieb:
ja schrieb:
VC ja
Auch bei _SECUREL_SCL == 0?...

-
Naja, probier es doch aus?
#include <cstdio> #include <vector> using namespace std; int main() { vector<int> foo(5); fill(foo.begin(), foo.end(), 1337); for(vector<int>::size_type i = 0; i < 10; ++i) printf("operator[] : %d , at() : %d\n", foo[i], foo.at(i)); }Verwurstet der VC++ 2008 im Release Mode zu (Pseudo-Code)
int __cdecl main(int argc, const char **argv, const char **envp) { int *v3; // eax@1 unsigned int v4; // ebx@1 int *v5; // esi@1 int v6; // eax@1 int v7; // ebx@1 int v8; // ebp@1 int v9; // esi@1 int v10; // edi@1 std::vector<int,std::allocator<int> > *v11; // ecx@1 int *v12; // edi@3 int *v13; // ecx@5 int *v14; // esi@12 int *v15; // eax@12 std::vector<int,std::allocator<int> > *v17; // [sp-14h] [bp-3Ch]@1 int v18; // [sp-10h] [bp-38h]@1 int v19; // [sp-Ch] [bp-34h]@1 int v20; // [sp-8h] [bp-30h]@1 int v21; // [sp-4h] [bp-2Ch]@1 std::vector<int,std::allocator<int> > foo; // [sp+0h] [bp-28h]@1 int v23; // [sp+18h] [bp-10h]@15 int v24; // [sp+1Ch] [bp-Ch]@1 int (*v25)(); // [sp+20h] [bp-8h]@1 int v26; // [sp+24h] [bp-4h]@1 v26 = -1; v25 = _ehhandler__main; v24 = v6; v21 = v7; v20 = v8; v19 = v9; v18 = v10; v17 = (std::vector<int,std::allocator<int> > *)((unsigned int)&v18 ^ __security_cookie); std__vector_int_std__allocator_int____vector_int_std__allocator_int__(v11, (unsigned int)&foo); v4 = 0; v26 = 0; v3 = foo._Mylast; v5 = foo._Mylast; if ( foo._Myfirst > foo._Mylast ) { __invalid_parameter_noinfo(v17, v18); v3 = foo._Mylast; } v12 = foo._Myfirst; if ( foo._Myfirst > v3 ) { __invalid_parameter_noinfo(v17, v18); v3 = foo._Mylast; } v13 = v12; if ( v12 != v5 ) { do { *v13 = 1337; ++v13; } while ( v13 != v5 ); v3 = foo._Mylast; } while ( 1 ) { if ( v4 >= (signed int)((char *)v3 - (char *)foo._Myfirst) >> 2 ) __invalid_parameter_noinfo(v17, v18); v14 = &foo._Myfirst[v4]; v15 = std__vector_int_std__allocator_int____at(v17, v4); _printf("operator[] : %d , at() : %d\n", *v14, *v15, v18); ++v4; if ( v4 >= 0xA ) break; v3 = foo._Mylast; } if ( foo._Mylast ) operator delete(foo._Mylast); foo._Mylast = 0; foo._Myend = 0; v23 = 0; operator delete(*(void **)&foo.baseclass_0.baseclass_0._Alaux.baseclass_0.dummy[0]); return 0; }bzw
.text:00401060 ; int __cdecl main(int argc, const char **argv, const char **envp) .text:00401060 _main proc near ; CODE XREF: __tmainCRTStartup+10Ap .text:00401060 .text:00401060 foo = std::vector<int,std::allocator<int> > ptr -28h .text:00401060 var_10 = dword ptr -10h .text:00401060 var_C = byte ptr -0Ch .text:00401060 var_8 = dword ptr -8 .text:00401060 var_4 = dword ptr -4 .text:00401060 argc = dword ptr 8 .text:00401060 argv = dword ptr 0Ch .text:00401060 envp = dword ptr 10h .text:00401060 .text:00401060 push ebp .text:00401061 mov ebp, esp .text:00401063 and esp, 0FFFFFFF8h .text:00401066 push 0FFFFFFFFh .text:00401068 push offset __ehhandler$_main .text:0040106D mov eax, large fs:0 .text:00401073 push eax .text:00401074 sub esp, 1Ch .text:00401077 push ebx .text:00401078 push ebp .text:00401079 push esi .text:0040107A push edi .text:0040107B mov eax, ___security_cookie .text:00401080 xor eax, esp .text:00401082 push eax ; this .text:00401083 lea eax, [esp+3Ch+var_C] .text:00401087 mov large fs:0, eax .text:0040108D lea eax, [esp+3Ch+foo] .text:00401091 push eax ; _Count .text:00401092 call ??0?$vector@HV?$allocator@H@std@@@std@@QAE@I@Z ; std::vector<int,std::allocator<int>>::vector<int,std::allocator<int>>(uint) .text:00401097 xor ebx, ebx ; _Pos .text:00401099 mov [esp+3Ch+var_4], ebx .text:0040109D mov eax, [esp+3Ch+foo._Mylast] .text:004010A1 mov ebp, ds:__imp___invalid_parameter_noinfo .text:004010A7 mov esi, eax .text:004010A9 cmp [esp+3Ch+foo._Myfirst], eax .text:004010AD jbe short loc_4010B5 .text:004010AF call ebp ; __imp___invalid_parameter_noinfo .text:004010B1 mov eax, [esp+3Ch+foo._Mylast] .text:004010B5 .text:004010B5 loc_4010B5: ; CODE XREF: _main+4Dj .text:004010B5 mov edi, [esp+3Ch+foo._Myfirst] .text:004010B9 cmp edi, eax .text:004010BB jbe short loc_4010C3 .text:004010BD call ebp ; __imp___invalid_parameter_noinfo .text:004010BF mov eax, [esp+3Ch+foo._Mylast] .text:004010C3 .text:004010C3 loc_4010C3: ; CODE XREF: _main+5Bj .text:004010C3 mov ecx, edi .text:004010C5 cmp edi, esi .text:004010C7 jz short loc_4010E1 .text:004010C9 lea esp, [esp+0] .text:004010D0 .text:004010D0 loc_4010D0: ; CODE XREF: _main+7Bj .text:004010D0 mov dword ptr [ecx], 539h .text:004010D6 add ecx, 4 .text:004010D9 cmp ecx, esi .text:004010DB jnz short loc_4010D0 .text:004010DD mov eax, [esp+3Ch+foo._Mylast] .text:004010E1 .text:004010E1 loc_4010E1: ; CODE XREF: _main+67j .text:004010E1 mov edi, ds:__imp__printf .text:004010E7 jmp short loc_4010F4 .text:004010E7 ; --------------------------------------------------------------------------- .text:004010E9 align 10h .text:004010F0 .text:004010F0 loc_4010F0: ; CODE XREF: _main+C5j .text:004010F0 mov eax, [esp+3Ch+foo._Mylast] .text:004010F4 .text:004010F4 loc_4010F4: ; CODE XREF: _main+87j .text:004010F4 sub eax, [esp+3Ch+foo._Myfirst] .text:004010F8 sar eax, 2 .text:004010FB cmp ebx, eax .text:004010FD jb short loc_401101 .text:004010FF call ebp ; __imp___invalid_parameter_noinfo .text:00401101 .text:00401101 loc_401101: ; CODE XREF: _main+9Dj .text:00401101 mov ecx, [esp+3Ch+foo._Myfirst] .text:00401105 lea eax, [esp+3Ch+foo] .text:00401109 lea esi, [ecx+ebx*4] .text:0040110C call ?at@?$vector@HV?$allocator@H@std@@@std@@QAEAAHI@Z ; std::vector<int,std::allocator<int>>::at(uint) .text:00401111 mov edx, [eax] .text:00401113 mov eax, [esi] .text:00401115 push edx .text:00401116 push eax .text:00401117 push offset Format ; "operator[] : %d , at() : %d\n" .text:0040111C call edi ; __imp__printf .text:0040111E inc ebx .text:0040111F add esp, 0Ch .text:00401122 cmp ebx, 0Ah .text:00401125 jb short loc_4010F0 .text:00401127 mov eax, [esp+38h+foo._Mylast] .text:0040112B xor esi, esi .text:0040112D cmp eax, esi .text:0040112F jz short loc_40113A .text:00401131 push eax ; void * .text:00401132 call ??3@YAXPAX@Z_0 ; operator delete(void *) .text:00401137 add esp, 4 .text:0040113A .text:0040113A loc_40113A: ; CODE XREF: _main+CFj .text:0040113A mov ecx, dword ptr [esp+38h+foo.baseclass_0.baseclass_0._Alaux.baseclass_0.dummy] .text:0040113E push ecx ; void * .text:0040113F mov [esp+3Ch+foo._Mylast], esi .text:00401143 mov [esp+3Ch+foo._Myend], esi .text:00401147 mov [esp+3Ch+var_10], esi .text:0040114B call ??3@YAXPAX@Z_0 ; operator delete(void *) .text:00401150 add esp, 4 .text:00401153 xor eax, eax .text:00401155 mov ecx, [esp+38h+var_8] .text:00401159 mov large fs:0, ecx .text:00401160 pop ecx .text:00401161 pop edi .text:00401162 pop esi .text:00401163 pop ebp .text:00401164 pop ebx .text:00401165 mov esp, ebp .text:00401167 pop ebp .text:00401168 retn
-
@Icematix:
Wie hast du den Pseudocode generieren lassen können?
-
drakon schrieb:
@Icematix:
Wie hast du den Pseudocode generieren lassen können?IDAPro 5.5 mit HexRays 1.1 (HexRays 1.2 ist die Bombe, erzeugt noch viel schöneren Pseudocode, absoluter Wahnsinn für Reverse Engineerer, hab ich leider noch nicht)
Kostet dich aber ~1800€, wenn du nicht die Wege des Illegalen beschreiten möchtest

-
Dachte ich doch, dass ich ein solches Feature in VS nicht übersehen könnte.

Danke für die Programme. Werde sie mir bei Gelegenheit mal anschauen.