{"action":"created","issue":{"url":"https://api.github.com/repos/kripken/emscripten/issues/3301","labels_url":"https://api.github.com/repos/kripken/emscripten/issues/3301/labels{/name}","comments_url":"https://api.github.com/repos/kripken/emscripten/issues/3301/comments","events_url":"https://api.github.com/repos/kripken/emscripten/issues/3301/events","html_url":"https://github.com/kripken/emscripten/issues/3301","id":65935737,"number":3301,"title":"Glitch in structure members access","user":{"login":"Olivier-myriad","id":11772212,"avatar_url":"https://avatars.githubusercontent.com/u/11772212?v=3","gravatar_id":"","url":"https://api.github.com/users/Olivier-myriad","html_url":"https://github.com/Olivier-myriad","followers_url":"https://api.github.com/users/Olivier-myriad/followers","following_url":"https://api.github.com/users/Olivier-myriad/following{/other_user}","gists_url":"https://api.github.com/users/Olivier-myriad/gists{/gist_id}","starred_url":"https://api.github.com/users/Olivier-myriad/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Olivier-myriad/subscriptions","organizations_url":"https://api.github.com/users/Olivier-myriad/orgs","repos_url":"https://api.github.com/users/Olivier-myriad/repos","events_url":"https://api.github.com/users/Olivier-myriad/events{/privacy}","received_events_url":"https://api.github.com/users/Olivier-myriad/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-04-02T14:12:11Z","updated_at":"2015-04-02T16:25:17Z","closed_at":"2015-04-02T14:19:15Z","body":"Hi,\r\n\r\nAfter trying \"Hello world\", I decided to give a shot with a more complex project.\r\n\r\nI then got an issue that I can reproduce each time, but is too embedded in my project (20 plain-C source files) to be extracted. \r\n\r\nHere is what I get, after working on some data structure:\r\nA function sets masque->lettres.items (unsigned long) to 1.\r\nThen, I have :\r\n\r\n`printf(\"Addr %08lx size %d content %lu\\n\",`\r\n`   (long)&(masque->lettres.items),`\r\n`   sizeof(masque->lettres.items),`\r\n`   masque->lettres.items);`\r\n\r\n`printf(\"Memory at %08lx = %lu\\n\",`\r\n`     (long)&(masque->lettres.items),`\r\n`     *(unsigned long *)&(masque->lettres.items));`\r\n\r\nWhatever I did before, the content of memory should be equal to the structure member. Hence, the output is :\r\n\r\n`Addr 005bdcf6 size 4 content 1703936`\r\n`Memory at 005bdcf6 = 1`\r\n\r\nHow can it be explained otherwise than an error in the Emscripten compiler?\r\n\r\nNote : I compiled my whole project using the -g4 option, as well as -s ALLOW_MEMORY_GROWTH=1.\r\n\r\nDoes anybody have a clue?\r\n\r\nThanks,\r\n"},"comment":{"url":"https://api.github.com/repos/kripken/emscripten/issues/comments/88965734","html_url":"https://github.com/kripken/emscripten/issues/3301#issuecomment-88965734","issue_url":"https://api.github.com/repos/kripken/emscripten/issues/3301","id":88965734,"user":{"login":"juj","id":225351,"avatar_url":"https://avatars.githubusercontent.com/u/225351?v=3","gravatar_id":"","url":"https://api.github.com/users/juj","html_url":"https://github.com/juj","followers_url":"https://api.github.com/users/juj/followers","following_url":"https://api.github.com/users/juj/following{/other_user}","gists_url":"https://api.github.com/users/juj/gists{/gist_id}","starred_url":"https://api.github.com/users/juj/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juj/subscriptions","organizations_url":"https://api.github.com/users/juj/orgs","repos_url":"https://api.github.com/users/juj/repos","events_url":"https://api.github.com/users/juj/events{/privacy}","received_events_url":"https://api.github.com/users/juj/received_events","type":"User","site_admin":false},"created_at":"2015-04-02T16:25:17Z","updated_at":"2015-04-02T16:25:17Z","body":"You are most likely seeing the effects of a previous write to a badly casted address, which makes it look as if the C cast works and the direct access doesn't. Here is an example, which works as expected with `#pragma pack`, and illustrates how accessing via a C cast corrupts the data and how a later access to that data may seem like C cast might work and direct access doesn't:\r\n\r\n\t#include <stdio.h>\r\n\t#include <inttypes.h>\r\n\r\n\t#pragma pack(2)\r\n\tstruct Foo\r\n\t{\r\n\t\tuint16_t a;\r\n\t\tuint32_t b;\r\n\t\tuint16_t c;\r\n\t};\r\n\r\n\tint main()\r\n\t{\r\n\t\tFoo f;\r\n\t\tf.a = 10;\r\n\t\tf.b = 42;\r\n\t\tf.c = 64;\r\n\t\tprintf(\"f.a <- 10, f.b <- 42, f.c <- 64.\\n\");\r\n\t\tprintf(\"alignment of a: %X. Value at a: %u\\n\", ((uintptr_t)&f.a) % 4, f.a);\r\n\t\tprintf(\"alignment of b: %X. Value at b: %u\\n\", ((uintptr_t)&f.b) % 4, f.b);\r\n\t\tprintf(\"alignment of b: %X. Value at b: %u\\n\", ((uintptr_t)&f.b) % 4, *(uint32_t*)&f.b);\r\n\t\tprintf(\"alignment of c: %X. Value at c: %u\\n\", ((uintptr_t)&f.c) % 4, f.c);\r\n\r\n\t\tuint32_t *data = (uint32_t*)&f.b;\r\n\t\t*data = 90;\r\n\t\tprintf(\"Bad attempted write to f.b <- 90.\\n\");\r\n\t\tprintf(\"After bad write: alignment of a: %X. Value at a: %u\\n\", ((uintptr_t)&f.a) % 4, f.a);\r\n\t\tprintf(\"After bad write: alignment of b: %X. Value at b: %u\\n\", ((uintptr_t)&f.b) % 4, f.b);\r\n\t\tprintf(\"After bad write: alignment of b: %X. Value at b: %u\\n\", ((uintptr_t)&f.b) % 4, *(uint32_t*)&f.b);\r\n\t\tprintf(\"After bad write: alignment of c: %X. Value at c: %u\\n\", ((uintptr_t)&f.c) % 4, f.c);\r\n\t}\r\n\r\nBuilding with `em++ x.cpp -g4 -s ALLOW_MEMORY_GROWTH=1 -o x.js`, and running `node x.js` gives\r\n\r\n\tf.a <- 10, f.b <- 42, f.c <- 64.\r\n\talignment of a: 0. Value at a: 10\r\n\talignment of b: 2. Value at b: 42\r\n\talignment of b: 2. Value at b: 2752522\r\n\talignment of c: 2. Value at c: 64\r\n\tBad attempted write to f.b <- 90.\r\n\tAfter bad write: alignment of a: 0. Value at a: 90\r\n\tAfter bad write: alignment of b: 2. Value at b: 0\r\n\tAfter bad write: alignment of b: 2. Value at b: 90\r\n\tAfter bad write: alignment of c: 2. Value at c: 64\r\n\r\nHowever this is just a guess, since I don't see your full code. In any case, compiling the same code with `-s SAFE_HEAP=1` gives added error checks so that it is possible to pinpoint locations where badly aligned loads or stores occurs:\r\n\r\n    f.a <- 10, f.b <- 42, f.c <- 64.\r\n    alignment of a: 0. Value at a: 10\r\n    alignment of b: 2. Value at b: 42\r\n    alignment error loading from address 1066, which was expected to be aligned to a\r\n     multiple of 4\r\n    alignment error loading from address 1066, which was expected to be aligned to a\r\n     multiple of 4\r\n\r\n    C:\\code\\emsdk\\emscripten\\incoming\\x.js:86\r\n          throw ex;\r\n                ^\r\n    abort(\"alignment error loading from address 1066, which was expected to be aligned to a multiple of 4\") at Error\r\n        at jsStackTrace (C:\\code\\emsdk\\emscripten\\incoming\\x.js:1239:13)\r\n        at stackTrace (C:\\code\\emsdk\\emscripten\\incoming\\x.js:1256:22)\r\n        at abort (C:\\code\\emsdk\\emscripten\\incoming\\x.js:10357:44)\r\n        at SAFE_HEAP_LOAD (C:\\code\\emsdk\\emscripten\\incoming\\x.js:384:27)\r\n        at _main (C:\\code\\emsdk\\emscripten\\incoming\\x.js:9903:8)\r\n        at Object.asm._main (C:\\code\\emsdk\\emscripten\\incoming\\x.js:10107:19)\r\n        at Object.callMain (C:\\code\\emsdk\\emscripten\\incoming\\x.js:10226:30)\r\n        at doRun (C:\\code\\emsdk\\emscripten\\incoming\\x.js:10284:60)\r\n        at run (C:\\code\\emsdk\\emscripten\\incoming\\x.js:10298:5)\r\n        at Object.<anonymous> (C:\\code\\emsdk\\emscripten\\incoming\\x.js:10381:1)\r\n\r\nso that is a good way to locate misbehaving code."}}